diff --git a/example-apps/swirlds-platform-base-example/build.gradle.kts b/example-apps/swirlds-platform-base-example/build.gradle.kts index 7f3e5f02a809..4f126e6c7ce3 100644 --- a/example-apps/swirlds-platform-base-example/build.gradle.kts +++ b/example-apps/swirlds-platform-base-example/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("application") - id("com.hedera.gradle.platform") -} +plugins { id("com.hedera.gradle.module.application") } mainModuleInfo { annotationProcessor("com.swirlds.config.processor") @@ -25,4 +22,4 @@ mainModuleInfo { runtimeOnly("com.swirlds.config.impl") } -application.mainClass.set("com.swirlds.platform.base.example.Application") +application.mainClass = "com.swirlds.platform.base.example.Application" diff --git a/gradle/aggregation/build.gradle.kts b/gradle/aggregation/build.gradle.kts index 6eca0a00a014..9cd157d0dfd1 100644 --- a/gradle/aggregation/build.gradle.kts +++ b/gradle/aggregation/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.hedera.gradle.reports") + id("com.hedera.gradle.report.code-coverage") } dependencies { diff --git a/gradle/development-branch.txt b/gradle/development-branch.txt new file mode 100644 index 000000000000..ce57f6456319 --- /dev/null +++ b/gradle/development-branch.txt @@ -0,0 +1 @@ +develop \ No newline at end of file diff --git a/gradle/jdk-version.txt b/gradle/jdk-version.txt new file mode 100644 index 000000000000..f222bf6f4c7a --- /dev/null +++ b/gradle/jdk-version.txt @@ -0,0 +1 @@ +21.0.4 diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.java.gradle.kts b/gradle/plugins/src/main/kotlin/com.hedera.gradle.java.gradle.kts deleted file mode 100644 index f5082aab887d..000000000000 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.java.gradle.kts +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2022-2024 Hedera Hashgraph, 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.adarshr.gradle.testlogger.theme.ThemeType -import com.autonomousapps.DependencyAnalysisSubExtension -import com.hedera.gradle.services.TaskLockService -import com.hedera.gradle.utils.Utils.versionTxt -import org.gradlex.javamodule.dependencies.tasks.ModuleDirectivesOrderingCheck -import org.gradlex.javamodule.dependencies.tasks.ModuleDirectivesScopeCheck - -plugins { - id("java") - id("jacoco") - id("checkstyle") - id("com.adarshr.test-logger") - id("com.autonomousapps.dependency-analysis") - id("com.hedera.gradle.lifecycle") - id("com.hedera.gradle.jpms-modules") - id("com.hedera.gradle.repositories") - id("com.hedera.gradle.spotless-java") - id("com.hedera.gradle.spotless-kotlin") -} - -version = - providers.fileContents(rootProject.layout.projectDirectory.versionTxt()).asText.get().trim() - -val javaVersionMajor = JavaVersion.VERSION_21 -val javaVersionPatch = "0.4" - -val currentJavaVersionMajor = JavaVersion.current() -val currentJavaVersion = providers.systemProperty("java.version").get() -val expectedJavaVersion = "$javaVersionMajor.$javaVersionPatch" - -if (currentJavaVersion != expectedJavaVersion) { - val message = - "Gradle runs with Java $currentJavaVersion. This project works best running with Java $expectedJavaVersion. " + - "\n - From commandline: change JAVA_HOME and/or PATH to point at Java $expectedJavaVersion installation." + - "\n - From IntelliJ: change 'Gradle JVM' in 'Gradle Settings' to point at Java $expectedJavaVersion installation." - - if (currentJavaVersionMajor.ordinal < javaVersionMajor.ordinal) { // fail if version is too old - throw (RuntimeException(message)) - } else { - logger.lifecycle("WARN: $message") - } -} - -java { - sourceCompatibility = javaVersionMajor - targetCompatibility = javaVersionMajor -} - -configurations.all { - // In case published versions of a module are also available, always prefer the local one - resolutionStrategy.preferProjectModules() -} - -jvmDependencyConflicts { - consistentResolution { - providesVersions(":aggregation") - platform(":hedera-dependency-versions") - } -} - -val consistentResolutionAttribute = Attribute.of("consistent-resolution", String::class.java) - -configurations.create("allDependencies") { - isCanBeConsumed = true - isCanBeResolved = false - sourceSets.all { - extendsFrom( - configurations[this.implementationConfigurationName], - configurations[this.compileOnlyConfigurationName], - configurations[this.runtimeOnlyConfigurationName], - configurations[this.annotationProcessorConfigurationName] - ) - } - attributes { - attribute(consistentResolutionAttribute, "global") - attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) - attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) - attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) - attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) - } -} - -configurations.getByName("mainRuntimeClasspath") { - attributes.attribute(consistentResolutionAttribute, "global") -} - -tasks.buildDependents { setGroup(null) } - -tasks.buildNeeded { setGroup(null) } - -tasks.jar { setGroup(null) } - -sourceSets.all { - // Remove 'classes' tasks from 'build' group to keep it cleaned up - tasks.named(classesTaskName) { group = null } - - // 'assemble' compiles all sources, including all test sources - tasks.assemble { dependsOn(tasks.named(classesTaskName)) } -} - -val writeGitProperties = - tasks.register("writeGitProperties") { - property("git.build.version", project.version) - @Suppress("UnstableApiUsage") - property( - "git.commit.id", - providers - .exec { commandLine("git", "rev-parse", "HEAD") } - .standardOutput - .asText - .map { it.trim() } - ) - @Suppress("UnstableApiUsage") - property( - "git.commit.id.abbrev", - providers - .exec { commandLine("git", "rev-parse", "HEAD") } - .standardOutput - .asText - .map { it.trim().substring(0, 7) } - ) - - destinationFile = layout.buildDirectory.file("generated/git/git.properties") - } - -tasks.processResources { from(writeGitProperties) } - -// ignore the content of 'git.properties' when using a classpath as task input -normalization.runtimeClasspath { ignore("git.properties") } - -tasks.withType().configureEach { - isPreserveFileTimestamps = false - isReproducibleFileOrder = true - filePermissions { unix("0664") } - dirPermissions { unix("0775") } -} - -tasks.jar { exclude("**/classpath.index") } - -val deactivatedCompileLintOptions = - listOf( - // In Gradle, a module does not see the upstream (not-yet-compiled) modules. This could - // only be solved by calling 'javac' with '--source-module-path' to make other sources - // known. But this is at odds with how Gradle's incremental compilation calls the - // compiler for a subset of Java files for each project individually. - "module", // module not found when doing 'exports to ...' - "serial", // serializable class ... has no definition of serialVersionUID - "processing", // No processor claimed any of these annotations: ... - "try", // auto-closeable resource ignore is never referenced... (AutoClosableLock) - "missing-explicit-ctor", // class ... declares no explicit constructors - - // Needed because we use deprecation internally and do not fix all uses right away - "removal", - "deprecation", - - // The following checks could be activated and fixed: - "this-escape", // calling public/protected method in constructor - "overrides", // overrides equals, but neither it ... overrides hashCode method - "unchecked", - "rawtypes" - ) - -tasks.withType().configureEach { - // Track the full Java version as input (e.g. 17.0.3 vs. 17.0.9). - // By default, Gradle only tracks the major version as defined in the toolchain (e.g. 17). - // Since the full version is encoded in 'module-info.class' files, it should be tracked as - // it otherwise leads to wrong build cache hits. - inputs.property("fullJavaVersion", currentJavaVersion) - - options.encoding = "UTF-8" - options.isFork = true // run compiler in separate JVM process (independent of toolchain setup) - options.compilerArgs.add("-implicit:none") - options.compilerArgs.add("-Werror") - options.compilerArgs.add("-Xlint:all,-" + deactivatedCompileLintOptions.joinToString(",-")) - - doLast { - // Make sure consistent line ending are used in files generated by annotation processors by - // rewriting generated files. - // To fix this problem at the root, one of these issues needs to be addressed upstream: - // - https://github.com/google/auto/issues/1656 - // - https://github.com/gradle/gradle/issues/27385 - if (System.lineSeparator() != "\n") { - destinationDirectory - .get() - .asFileTree - .filter { it.extension != "class" } - .forEach { - val content = it.readText() - val normalizedContent = content.replace(System.lineSeparator(), "\n") - if (content != normalizedContent) { - it.writeText(normalizedContent) - } - } - } - } -} - -tasks.withType().configureEach { - options { - this as StandardJavadocDocletOptions - encoding = "UTF-8" - tags( - "apiNote:a:API Note:", - "implSpec:a:Implementation Requirements:", - "implNote:a:Implementation Note:" - ) - options.windowTitle = "Hedera Consensus Node" - options.memberLevel = JavadocMemberLevel.PACKAGE - addStringOption("Xdoclint:all,-missing", "-Xwerror") - } -} - -@Suppress("UnstableApiUsage") -testing.suites { - named("test") { - useJUnitJupiter() - targets.all { - testTask { - group = "build" - maxHeapSize = "4g" - // Some tests overlap due to using the same temp folders within one project - // maxParallelForks = 4 <- set this, once tests can run in parallel - } - } - } - // remove automatically added compile time dependencies, as we want to define them all - // explicitly - withType { - configurations.getByName(sources.implementationConfigurationName) { - withDependencies { - removeIf { it.group == "org.junit.jupiter" && it.name == "junit-jupiter" } - } - } - dependencies { runtimeOnly("org.junit.jupiter:junit-jupiter-engine") } - } -} - -// If user gave the argument '-PactiveProcessorCount', then do: -// - run all test tasks in sequence -// - give the -XX:ActiveProcessorCount argument to the test JVMs -val activeProcessorCount = providers.gradleProperty("activeProcessorCount") - -if (activeProcessorCount.isPresent) { - tasks.withType().configureEach { - usesService( - gradle.sharedServices.registerIfAbsent("lock", TaskLockService::class) { - maxParallelUsages = 1 - } - ) - jvmArgs("-XX:ActiveProcessorCount=${activeProcessorCount.get()}") - } -} - -tasks.jacocoTestReport { - // Configure Jacoco so it outputs XML reports (needed by SonarCloud) - reports { - xml.required = true - html.required = true - } -} - -testlogger { - theme = ThemeType.MOCHA_PARALLEL - slowThreshold = 10000 - showPassed = false - showSkipped = false - showStandardStreams = true - showPassedStandardStreams = false - showSkippedStandardStreams = false - showFailedStandardStreams = true -} - -tasks.assemble { dependsOn(tasks.javadoc) } - -tasks.check { dependsOn(tasks.jacocoTestReport) } - -tasks.named("qualityGate") { dependsOn(tasks.withType()) } - -// ordering check is done by SortModuleInfoRequiresStep -tasks.withType { enabled = false } - -tasks.withType().configureEach { - // When doing a 'qualityGate' run, make sure spotlessApply is done before doing compilation and - // other checks based on compiled code - mustRunAfter(tasks.spotlessApply) -} - -// Do not report dependencies from one source set to another as 'required'. -// In particular, in case of test fixtures, the analysis would suggest to -// add as testModuleInfo { require(...) } to the main module. This is -// conceptually wrong, because in whitebox testing the 'main' and 'test' -// module are conceptually considered one module (main module extended with tests) -configure { issues { onAny { exclude(project.path) } } } - -checkstyle { toolVersion = "10.12.7" } - -tasks.withType().configureEach { - reports { - xml.required = true - html.required = true - sarif.required = true - } -} - -tasks.withType().configureEach { - // Do not yet run things on the '--module-path' - modularity.inferModulePath = false - if (name.endsWith("main()")) { - notCompatibleWithConfigurationCache("JavaExec created by IntelliJ") - } -} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.repositories.gradle.kts b/gradle/plugins/src/main/kotlin/com.hedera.gradle.repositories.gradle.kts deleted file mode 100644 index 734cf240f7eb..000000000000 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.repositories.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016-2024 Hedera Hashgraph, 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. - */ - -repositories { - mavenCentral() - maven { url = uri("https://us-maven.pkg.dev/swirlds-registry/maven-prerelease-channel") } - maven { url = uri("https://us-maven.pkg.dev/swirlds-registry/maven-develop-commits") } - maven { url = uri("https://us-maven.pkg.dev/swirlds-registry/maven-adhoc-commits") } - maven { url = uri("https://us-maven.pkg.dev/swirlds-registry/maven-develop-daily-snapshots") } - maven { url = uri("https://us-maven.pkg.dev/swirlds-registry/maven-develop-snapshots") } - maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } - maven { - url = uri("https://hyperledger.jfrog.io/artifactory/besu-maven") - content { includeGroupByRegex("org\\.hyperledger\\..*") } - } - maven { - url = uri("https://artifacts.consensys.net/public/maven/maven/") - content { includeGroupByRegex("tech\\.pegasys(\\..*)?") } - } - maven { url = uri("https://oss.sonatype.org/content/repositories/comhederahashgraph-1502") } - maven { url = uri("https://oss.sonatype.org/content/repositories/comhederahashgraph-1531") } -} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.shadow-jar.gradle.kts b/gradle/plugins/src/main/kotlin/com.hedera.gradle.shadow-jar.gradle.kts deleted file mode 100644 index d2bf1148e4d5..000000000000 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.shadow-jar.gradle.kts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, 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.github.jengelman.gradle.plugins.shadow.internal.DefaultDependencyFilter -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -plugins { - id("java") - id("com.github.johnrengelman.shadow") -} - -tasks.withType().configureEach { - group = "shadow" - from(sourceSets.main.get().output) - mergeServiceFiles() - - // There is an issue in the shadow plugin that it automatically accesses the - // files in 'runtimeClasspath' while Gradle is building the task graph. - // See: https://github.com/johnrengelman/shadow/issues/882 - dependencyFilter = NoResolveDependencyFilter() -} - -class NoResolveDependencyFilter : DefaultDependencyFilter(project) { - override fun resolve(configuration: FileCollection): FileCollection { - return configuration - } -} diff --git a/gradle/plugins/src/main/kotlin/com/hedera/gradle/utils/Utils.kt b/gradle/plugins/src/main/kotlin/com/hedera/gradle/utils/Utils.kt deleted file mode 100644 index 948ce171e8b6..000000000000 --- a/gradle/plugins/src/main/kotlin/com/hedera/gradle/utils/Utils.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2022-2024 Hedera Hashgraph, 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. - */ - -package com.hedera.gradle.utils - -import java.io.OutputStream -import java.io.PrintStream -import org.gradle.api.file.Directory -import org.gradle.api.file.RegularFile - -object Utils { - // Find the version.txt in the root of the repository, independent of - // which build is started from where. - @JvmStatic - fun Directory.versionTxt(): RegularFile = - file("version.txt").let { if (it.asFile.exists()) it else this.dir("..").versionTxt() } - - @JvmStatic - fun generateProjectVersionReport(version: String, ostream: OutputStream) { - val writer = PrintStream(ostream, false, Charsets.UTF_8) - - ostream.use { - writer.use { - // Writer headers - writer.println("### Deployed Version Information") - writer.println() - writer.println("| Artifact Name | Version Number |") - writer.println("| --- | --- |") - // Write table rows - writer.printf("| %s | %s |\n", "hedera-node", version) - writer.printf("| %s | %s |\n", "platform-sdk", version) - writer.flush() - ostream.flush() - } - } - } -} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b4155759..df97d72b8b91 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.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/hapi/build.gradle.kts b/hapi/build.gradle.kts index fae3da6548a2..b9ad50e0c89b 100644 --- a/hapi/build.gradle.kts +++ b/hapi/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.protobuf") - id("com.hedera.gradle.services-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.protobuf") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.pbj.pbj-compiler") version "0.9.2" } diff --git a/hedera-dependency-versions/build.gradle.kts b/hedera-dependency-versions/build.gradle.kts index a3963d6c8408..3ee65a86dc72 100644 --- a/hedera-dependency-versions/build.gradle.kts +++ b/hedera-dependency-versions/build.gradle.kts @@ -15,7 +15,8 @@ */ plugins { - id("com.hedera.gradle.versions") + id("com.hedera.gradle.base.lifecycle") + id("com.hedera.gradle.base.jpms-modules") } dependencies { diff --git a/gradle/plugins/build.gradle.kts b/hedera-gradle-conventions/build.gradle.kts similarity index 73% rename from gradle/plugins/build.gradle.kts rename to hedera-gradle-conventions/build.gradle.kts index ee5561644f57..491f70037df8 100644 --- a/gradle/plugins/build.gradle.kts +++ b/hedera-gradle-conventions/build.gradle.kts @@ -15,18 +15,18 @@ */ plugins { - // Support convention plugins written in Kotlin. Convention plugins are build scripts in - // 'src/main' that automatically become available as plugins in the main build. `kotlin-dsl` + id("com.gradle.plugin-publish") version "1.2.1" } -repositories { gradlePluginPortal() } +version = "0.1.0" + +group = "com.hedera.hashgraph" dependencies { implementation("com.adarshr:gradle-test-logger-plugin:4.0.0") implementation("com.autonomousapps:dependency-analysis-gradle-plugin:2.0.1") implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") - implementation("com.github.johnrengelman:shadow:8.1.1") implementation("com.google.protobuf:protobuf-gradle-plugin:0.9.4") implementation("com.gradle:develocity-gradle-plugin:3.18") implementation( @@ -34,8 +34,19 @@ dependencies { ) implementation("io.github.gradle-nexus:publish-plugin:1.3.0") implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") + implementation("net.ltgt.gradle:gradle-errorprone-plugin:4.0.1") implementation("net.swiftzer.semver:semver:1.3.0") implementation("org.gradlex:extra-java-module-info:1.9") implementation("org.gradlex:jvm-dependency-conflict-resolution:2.1.2") implementation("org.gradlex:java-module-dependencies:1.7") } + +gradlePlugin { + website = "https://github.com/hashgraph/hedera-gradle-conventions" + vcsUrl = "https://github.com/hashgraph/hedera-gradle-conventions" + plugins.configureEach { + description = "One of the Gradle convention plugins used in the Hedera organisation" + @Suppress("UnstableApiUsage") + tags = listOf("conventions", "java", "modules", "jpms") + } +} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.services.gradle.kts b/hedera-gradle-conventions/settings.gradle.kts similarity index 74% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.services.gradle.kts rename to hedera-gradle-conventions/settings.gradle.kts index b12ff59f1ee7..ea8272193b69 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.services.gradle.kts +++ b/hedera-gradle-conventions/settings.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2024 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,6 @@ * limitations under the License. */ -plugins { - id("java-library") - id("com.hedera.gradle.java") -} +rootProject.name = "hedera-gradle-conventions" + +dependencyResolutionManagement { @Suppress("UnstableApiUsage") repositories.gradlePluginPortal() } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.jpms-modules.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.jpms-modules.gradle.kts similarity index 83% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.jpms-modules.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.jpms-modules.gradle.kts index f5c2ca21b350..28f0b8bd9258 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.jpms-modules.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.jpms-modules.gradle.kts @@ -215,6 +215,24 @@ extraJavaModuleInfo { module("net.ltgt.gradle.incap:incap", "net.ltgt.gradle.incap") module("org.jetbrains.kotlinx:kotlinx-metadata-jvm", "kotlinx.metadata.jvm") + // Annotation processing - error prone + module( + "com.github.kevinstern:software-and-algorithms", + "com.github.kevinstern.software_and_algorithms" + ) + module("com.google.auto.value:auto-value-annotations", "com.google.auto.value.annotations") + module("com.google.errorprone:error_prone_annotation", "com.google.errorprone.annotation") + module("com.google.errorprone:error_prone_check_api", "com.google.errorprone.check.api") + module("com.google.errorprone:error_prone_core", "com.google.errorprone.core") + module( + "com.google.errorprone:error_prone_type_annotations", + "com.google.errorprone.type.annotations" + ) + module("com.uber.nullaway:nullaway", "com.uber.nullaway") + module("io.github.eisop:dataflow-errorprone", "org.checkerframework.dataflow") + module("io.github.java-diff-utils:java-diff-utils", "io.github.javadiffutils") + module("io.grpc:grpc-java-api-checker", "io.grpc.java.api.checker") + // Testing only module("com.google.jimfs:jimfs", "com.google.jimfs") module("org.awaitility:awaitility", "awaitility") @@ -242,3 +260,38 @@ extraJavaModuleInfo { module("org.testcontainers:testcontainers", "org.testcontainers") module("org.mockito:mockito-junit-jupiter", "org.mockito.junit.jupiter") } + +// Configure consistent resolution across the whole project +val consistentResolutionAttribute = Attribute.of("consistent-resolution", String::class.java) + +configurations.create("allDependencies") { + isCanBeConsumed = true + isCanBeResolved = false + sourceSets.all { + extendsFrom( + configurations[this.implementationConfigurationName], + configurations[this.compileOnlyConfigurationName], + configurations[this.runtimeOnlyConfigurationName], + configurations[this.annotationProcessorConfigurationName] + ) + } + attributes { + attribute(consistentResolutionAttribute, "global") + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) + } +} + +jvmDependencyConflicts.consistentResolution { + providesVersions(":aggregation") + platform(":hedera-dependency-versions") +} + +configurations.getByName("mainRuntimeClasspath") { + attributes.attribute(consistentResolutionAttribute, "global") +} + +// In case published versions of a module are also available, always prefer the local one +configurations.all { resolutionStrategy.preferProjectModules() } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.lifecycle.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.lifecycle.gradle.kts similarity index 79% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.lifecycle.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.lifecycle.gradle.kts index 1c74e298998c..8e4bb3499cc1 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.lifecycle.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.lifecycle.gradle.kts @@ -14,19 +14,21 @@ * limitations under the License. */ -plugins { - id("base") - id("com.diffplug.spotless") -} +plugins { id("base") } -// Convenience for local development: when running './gradlew' without any parameters just show the -// tasks from the 'build' group +// Convenience for local development: when running './gradlew' without any parameters show the tasks +// from the 'build' group defaultTasks("tasks") +tasks.register("qualityCheck") { + group = "build" + description = "Run all spotless and quality checks." + dependsOn(tasks.assemble) +} + tasks.register("qualityGate") { group = "build" description = "Apply spotless rules and run all quality checks." - dependsOn(tasks.spotlessApply) dependsOn(tasks.assemble) } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.services-publish.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.version.gradle.kts similarity index 66% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.services-publish.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.version.gradle.kts index 57ed149ed3de..df25ecc2c551 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.services-publish.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.base.version.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2016-2024 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,10 @@ * limitations under the License. */ -plugins { - id("java") - id("com.hedera.gradle.maven-publish") -} +version = + providers + .fileContents(isolated.rootProject.projectDirectory.file("version.txt")) + .asText + .orElse(provider { throw RuntimeException("version.txt file not found") }) + .get() + .trim() diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.settings.settings.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.build.settings.gradle.kts similarity index 53% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.settings.settings.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.build.settings.gradle.kts index 5da00ecb2321..1e63c2079150 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.settings.settings.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.build.settings.gradle.kts @@ -17,53 +17,11 @@ import org.gradlex.javamodule.dependencies.initialization.JavaModulesExtension import org.gradlex.javamodule.dependencies.initialization.RootPluginsExtension -pluginManagement { - repositories { - gradlePluginPortal() - mavenCentral() - maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } - } -} - plugins { - id("com.gradle.develocity") id("org.gradlex.java-module-dependencies") -} - -// Plugins that are global, but are applied to the "root project" instead of settings. -// by having this block here, we do not require a "build.gradle.kts" in the repository roots. -configure { id("com.hedera.gradle.root") } - -// Enable Gradle Build Scan -develocity { - buildScan { - termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use" - termsOfUseAgree = "yes" - publishing.onlyIf { false } // only publish with explicit '--scan' - } -} - -val isCiServer = System.getenv().containsKey("CI") -val gradleCacheUsername: String? = System.getenv("GRADLE_CACHE_USERNAME") -val gradleCachePassword: String? = System.getenv("GRADLE_CACHE_PASSWORD") -val gradleCacheAuthorized = - (gradleCacheUsername?.isNotEmpty() ?: false) && (gradleCachePassword?.isNotEmpty() ?: false) - -buildCache { - remote { - url = uri("https://cache.gradle.hedera.svcs.eng.swirldslabs.io/cache/") - isPush = isCiServer && gradleCacheAuthorized - - isUseExpectContinue = true - isEnabled = !gradle.startParameter.isOffline - - if (isCiServer && gradleCacheAuthorized) { - credentials { - username = gradleCacheUsername - password = gradleCachePassword - } - } - } + id("com.hedera.gradle.feature.build-cache") + id("com.hedera.gradle.feature.repositories") + id("com.hedera.gradle.report.develocity") } // Allow projects inside a build to be addressed by dependency coordinates notation. @@ -73,8 +31,24 @@ includeBuild(".") configure { // Project to aggregate code coverage data for the whole repository into one report - module("gradle/aggregation") + module("gradle/aggregation") { + plugin("java") + plugin("com.hedera.gradle.base.jpms-modules") + } // "BOM" with versions of 3rd party dependencies versions("hedera-dependency-versions") } + +// Plugins that are global, but are applied to the "root project" instead of settings. +// by having this block here, we do not require a "build.gradle.kts" in the repository roots. +configure { + id("com.hedera.gradle.base.lifecycle") + id("com.hedera.gradle.feature.publish-maven-central.root") + id("com.hedera.gradle.feature.versioning") + id("com.hedera.gradle.check.spotless") + id("com.hedera.gradle.check.spotless-kotlin") + id("com.hedera.gradle.check.spotless-markdown") + id("com.hedera.gradle.check.spotless-misc") + id("com.hedera.gradle.check.spotless-yaml") +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.dependencies.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.dependencies.gradle.kts new file mode 100644 index 000000000000..f3fd64a88792 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.dependencies.gradle.kts @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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.autonomousapps.DependencyAnalysisSubExtension +import org.gradlex.javamodule.dependencies.tasks.ModuleDirectivesOrderingCheck +import org.gradlex.javamodule.dependencies.tasks.ModuleDirectivesScopeCheck + +plugins { + id("com.autonomousapps.dependency-analysis") + id("com.hedera.gradle.base.lifecycle") + id("com.hedera.gradle.base.jpms-modules") +} + +// ordering check is done by SortModuleInfoRequiresStep +tasks.withType { enabled = false } + +// Do not report dependencies from one source set to another as 'required'. +// In particular, in case of test fixtures, the analysis would suggest to +// add as testModuleInfo { require(...) } to the main module. This is +// conceptually wrong, because in whitebox testing the 'main' and 'test' +// module are conceptually considered one module (main module extended with tests) +configure { issues { onAny { exclude(project.path) } } } + +tasks.named("qualityGate") { dependsOn(tasks.withType()) } diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.errorprone.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.errorprone.gradle.kts new file mode 100644 index 000000000000..010868cd7c52 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.errorprone.gradle.kts @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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 net.ltgt.gradle.errorprone.errorprone + +plugins { + id("java") + id("net.ltgt.errorprone") +} + +dependencies { + // https://github.com/google/error-prone + // https://errorprone.info/ + errorprone("com.google.errorprone:error_prone_core:2.32.0") + + // https://github.com/uber/NullAway + errorprone("com.uber.nullaway:nullaway:0.11.3") + + // https://github.com/grpc/grpc-java-api-checker + errorprone("io.grpc:grpc-java-api-checker:1.1.0") +} + +tasks.withType().configureEach { + options.errorprone { + // https://github.com/uber/NullAway + warn("NullAway") + option("NullAway:AnnotatedPackages", "com.hedera.hashgraph.sdk") + option("NullAway:TreatGeneratedAsUnannotated", "true") + + // https://github.com/grpc/grpc-java-api-checker + disable("GrpcExperimentalApi") + warn("GrpcInternal") + + // Enable _all_ checks then selectively disable checks + allDisabledChecksAsWarnings = true + disable("BooleanParameter") + disable("FieldCanBeFinal") + disable("Finally") + disable("FutureReturnValueIgnored") + disable("InlineMeSuggester") + disable("ThreadJoinLoop") + disable("ThrowSpecificExceptions") + disable("TryFailRefactoring") + disable("UngroupedOverloads") + disable("UnnecessaryDefaultInEnumSwitch") + + // Ignore generated and protobuf code + disableWarningsInGeneratedCode = true + excludedPaths = ".*generated.*" + } +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.javac-lint.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.javac-lint.gradle.kts new file mode 100644 index 000000000000..904c4a3090dc --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.javac-lint.gradle.kts @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +plugins { id("java") } + +val deactivatedCompileLintOptions = + listOf( + // In Gradle, a module does not see the upstream (not-yet-compiled) modules. This could + // only be solved by calling 'javac' with '--source-module-path' to make other sources + // known. But this is at odds with how Gradle's incremental compilation calls the + // compiler for a subset of Java files for each project individually. + "module", // module not found when doing 'exports to ...' + "serial", // serializable class ... has no definition of serialVersionUID + "processing", // No processor claimed any of these annotations: ... + "try", // auto-closeable resource ignore is never referenced... (AutoClosableLock) + "missing-explicit-ctor", // class ... declares no explicit constructors + + // Needed because we use deprecation internally and do not fix all uses right away + "removal", + "deprecation", + + // The following checks could be activated and fixed: + "this-escape", // calling public/protected method in constructor + "overrides", // overrides equals, but neither it ... overrides hashCode method + "unchecked", + "rawtypes" + ) + +tasks.withType().configureEach { + options.compilerArgs.add("-implicit:none") + options.compilerArgs.add("-Werror") + options.compilerArgs.add("-Xlint:all,-" + deactivatedCompileLintOptions.joinToString(",-")) +} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-java.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-java.gradle.kts similarity index 98% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-java.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-java.gradle.kts index 984b2cece001..f965bfd6b185 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-java.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-java.gradle.kts @@ -18,7 +18,7 @@ import com.hedera.gradle.spotless.RepairDashedCommentsFormatterStep import com.hedera.gradle.spotless.SortModuleInfoRequiresStep import com.hedera.gradle.spotless.StripOldLicenseFormatterStep -plugins { id("com.hedera.gradle.spotless") } +plugins { id("com.diffplug.spotless") } spotless { java { diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-kotlin.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-kotlin.gradle.kts similarity index 78% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-kotlin.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-kotlin.gradle.kts index 68fcb3923015..9963652d7d6d 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-kotlin.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-kotlin.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.spotless") } +plugins { id("com.diffplug.spotless") } spotless { kotlinGradle { @@ -39,8 +39,18 @@ spotless { */${"\n\n"} """ .trimIndent(), - "(import|plugins|pluginManagement|dependencyResolutionManagement|repositories|tasks|allprojects|subprojects)" + "(import|plugins|pluginManagement|dependencyResolutionManagement|repositories|tasks|allprojects|subprojects|buildCache|version)" ) .updateYearWithLatest(true) } + + if (project.parent == null) { + // If this is the root project, we also check Gradle plugin scripts + kotlinGradle { target("gradle/plugins/**/*.gradle.kts") } + kotlin { + // For the Kotlin classes (*.kt files) + ktfmt().kotlinlangStyle() + target("gradle/plugins/**/*.kt") + } + } } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-markdown.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-markdown.gradle.kts similarity index 90% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-markdown.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-markdown.gradle.kts index 1505c1a7c80e..df46529caab0 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless-markdown.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-markdown.gradle.kts @@ -14,11 +14,12 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.spotless") } +plugins { id("com.diffplug.spotless") } spotless { flexmark { target("**/*.md") + targetExclude("platform-sdk/sdk/**") flexmark() trimTrailingWhitespace() indentWithSpaces() diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.platform.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-misc.gradle.kts similarity index 67% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.platform.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-misc.gradle.kts index b12ff59f1ee7..739d6282c462 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.platform.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-misc.gradle.kts @@ -14,7 +14,16 @@ * limitations under the License. */ -plugins { - id("java-library") - id("com.hedera.gradle.java") +plugins { id("com.diffplug.spotless") } + +spotless { + format("misc") { + // define the files to apply `misc` to + target(".gitignore") + + // define the steps to apply to those files + trimTrailingWhitespace() + indentWithSpaces() + endWithNewline() + } } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-yaml.gradle.kts similarity index 82% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-yaml.gradle.kts index 4c027596fe37..d3c1a05186af 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.spotless.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless-yaml.gradle.kts @@ -17,22 +17,6 @@ plugins { id("com.diffplug.spotless") } spotless { - // Disable the automatic application of Spotless to all source sets when the check task is run. - isEnforceCheck = false - - // optional: limit format enforcement to just the files changed by this feature branch - ratchetFrom("origin/develop") - - format("misc") { - // define the files to apply `misc` to - target(".gitignore") - - // define the steps to apply to those files - trimTrailingWhitespace() - indentWithSpaces() - endWithNewline() - } - format("actionYaml") { target(".github/workflows/*.yaml") /* diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless.gradle.kts new file mode 100644 index 000000000000..3e4437297a51 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.check.spotless.gradle.kts @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022-2024 Hedera Hashgraph, 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. + */ + +plugins { + id("com.hedera.gradle.base.lifecycle") + id("com.diffplug.spotless") +} + +spotless { + // Disable the automatic application of Spotless to all source sets when the check task is run. + isEnforceCheck = false + + // limit format enforcement to just the files changed by this feature branch + @Suppress("UnstableApiUsage") + ratchetFrom( + "origin/" + + providers + .fileContents( + isolated.rootProject.projectDirectory.file("gradle/development-branch.txt") + ) + .asText + .getOrElse("main") + ) +} + +tasks.withType().configureEach { + // When doing a 'qualityGate' run, make sure spotlessApply is done before doing compilation and + // other checks based on compiled code + mustRunAfter(tasks.spotlessApply) +} + +tasks.named("qualityCheck") { dependsOn(tasks.spotlessCheck) } + +tasks.named("qualityGate") { dependsOn(tasks.spotlessApply) } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.benchmark.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.benchmark.gradle.kts similarity index 100% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.benchmark.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.benchmark.gradle.kts diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.build-cache.settings.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.build-cache.settings.gradle.kts new file mode 100644 index 000000000000..0fcf2bd16a55 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.build-cache.settings.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +buildCache { + remote { + url = uri("https://cache.gradle.hedera.svcs.eng.swirldslabs.io/cache/") + + isUseExpectContinue = true + isEnabled = !gradle.startParameter.isOffline + + val isCiServer = providers.environmentVariable("CI").getOrElse("false").toBoolean() + val gradleCacheUsername = providers.environmentVariable("GRADLE_CACHE_USERNAME") + val gradleCachePassword = providers.environmentVariable("GRADLE_CACHE_PASSWORD") + if (isCiServer && gradleCacheUsername.isPresent && gradleCachePassword.isPresent) { + isPush = true + credentials { + username = gradleCacheUsername.get() + password = gradleCachePassword.get() + } + } + } +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.git-properties-file.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.git-properties-file.gradle.kts new file mode 100644 index 000000000000..9439576aca27 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.git-properties-file.gradle.kts @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +plugins { id("java") } + +tasks.register("writeGitProperties") { + property("git.build.version", project.version) + @Suppress("UnstableApiUsage") + property( + "git.commit.id", + providers + .exec { commandLine("git", "rev-parse", "HEAD") } + .standardOutput + .asText + .map { it.trim() } + ) + @Suppress("UnstableApiUsage") + property( + "git.commit.id.abbrev", + providers + .exec { commandLine("git", "rev-parse", "HEAD") } + .standardOutput + .asText + .map { it.trim().substring(0, 7) } + ) + + destinationFile = layout.buildDirectory.file("generated/git/git.properties") +} + +tasks.processResources { from(tasks.named("writeGitProperties")) } + +// ignore the content of 'git.properties' when using a classpath as task input +normalization.runtimeClasspath { ignore("git.properties") } diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-compile.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-compile.gradle.kts new file mode 100644 index 000000000000..df745d90180e --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-compile.gradle.kts @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +plugins { id("java") } + +@Suppress("UnstableApiUsage") +val fullJavaVersion = + providers + .fileContents(isolated.rootProject.projectDirectory.file("gradle/jdk-version.txt")) + .asText + .orElse(provider { throw RuntimeException("gradle/jdk-version.txt file not found") }) + .get() + .trim() +val majorJavaVersion = JavaVersion.toVersion(fullJavaVersion) +val currentJavaVersion = providers.systemProperty("java.version").get() + +if (currentJavaVersion != fullJavaVersion) { + val message = + "Gradle runs with Java $currentJavaVersion. This project works best running with Java $fullJavaVersion. " + + "\n - From commandline: change JAVA_HOME and/or PATH to point at Java $fullJavaVersion installation." + + "\n - From IntelliJ: change 'Gradle JVM' in 'Gradle Settings' to point at Java $fullJavaVersion installation." + + logger.lifecycle("WARN: $message") +} + +java { + sourceCompatibility = majorJavaVersion + targetCompatibility = majorJavaVersion +} + +tasks.withType().configureEach { + // Track the full Java version as input (e.g. 17.0.3 vs. 17.0.9). + // By default, Gradle only tracks the major version as defined in the toolchain (e.g. 17). + // Since the full version is encoded in 'module-info.class' files, it should be tracked as + // it otherwise leads to wrong build cache hits. + inputs.property("fullJavaVersion", currentJavaVersion) + + options.encoding = "UTF-8" + options.isFork = true // run compiler in separate JVM process (independent of toolchain setup) + + doLast { + // Make sure consistent line ending are used in files generated by annotation processors by + // rewriting generated files. + // To fix this problem at the root, one of these issues needs to be addressed upstream: + // - https://github.com/google/auto/issues/1656 + // - https://github.com/gradle/gradle/issues/27385 + if (System.lineSeparator() != "\n") { + destinationDirectory + .get() + .asFileTree + .filter { it.extension != "class" } + .forEach { + val content = it.readText() + val normalizedContent = content.replace(System.lineSeparator(), "\n") + if (content != normalizedContent) { + it.writeText(normalizedContent) + } + } + } + } +} + +tasks.withType().configureEach { + isPreserveFileTimestamps = false + isReproducibleFileOrder = true + filePermissions { unix("0664") } + dirPermissions { unix("0775") } +} + +sourceSets.all { + // Remove 'classes' tasks from 'build' group to keep it cleaned up + tasks.named(classesTaskName) { group = null } + + // 'assemble' compiles all sources, including all test sources + tasks.assemble { dependsOn(tasks.named(classesTaskName)) } +} + +tasks.buildDependents { setGroup(null) } + +tasks.buildNeeded { setGroup(null) } + +tasks.jar { setGroup(null) } diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-doc.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-doc.gradle.kts new file mode 100644 index 000000000000..4a0f3baf4d4f --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-doc.gradle.kts @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +plugins { id("java") } + +tasks.withType().configureEach { + options { + this as StandardJavadocDocletOptions + encoding = "UTF-8" + tags( + "apiNote:a:API Note:", + "implSpec:a:Implementation Requirements:", + "implNote:a:Implementation Note:" + ) + options.windowTitle = "Hedera Consensus Node" + options.memberLevel = JavadocMemberLevel.PACKAGE + addStringOption("Xdoclint:all,-missing", "-Xwerror") + } +} + +tasks.assemble { dependsOn(tasks.javadoc) } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.versions.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-execute.gradle.kts similarity index 64% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.versions.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-execute.gradle.kts index 661037d92d75..11899cba5480 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.versions.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.java-execute.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC + * Copyright (C) 2024 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,12 @@ * limitations under the License. */ -plugins { - id("java-platform") - id("com.hedera.gradle.jpms-modules") - id("org.gradlex.java-module-versions") -} - -javaPlatform { allowDependencies() } +plugins { id("java") } -tasks.register("releaseMavenCentral") +tasks.withType().configureEach { + // Do not yet run things on the '--module-path' + modularity.inferModulePath = false + if (name.endsWith("main()")) { + notCompatibleWithConfigurationCache("JavaExec created by IntelliJ") + } +} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.protobuf.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.protobuf.gradle.kts similarity index 98% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.protobuf.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.protobuf.gradle.kts index 1f2b29332f6c..83feca4c8017 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.protobuf.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.protobuf.gradle.kts @@ -17,7 +17,7 @@ import com.google.protobuf.gradle.id plugins { - id("com.hedera.gradle.services") + id("java") id("com.google.protobuf") } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.platform-publish.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-artifactregistry.gradle.kts similarity index 74% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.platform-publish.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-artifactregistry.gradle.kts index e2983169da5f..ce5bfaa26001 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.platform-publish.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-artifactregistry.gradle.kts @@ -14,20 +14,12 @@ * limitations under the License. */ -plugins { - id("java") - id("com.hedera.gradle.maven-publish") -} +plugins { id("maven-publish") } -if ( - gradle.startParameter.taskNames.any { it.startsWith("release") || it.contains("MavenCentral") } -) { - // We apply the 'artifactregistry' plugin conditionally, as there are two issues: - // 1. It does not support configuration cache. - // https://github.com/GoogleCloudPlatform/artifact-registry-maven-tools/issues/85 - // 2. It does not interact well with the 'gradle-nexus.publish-plugin' plugin, causing: - // 'No staging repository with name sonatype created' during IDE import - publishing.repositories.remove(publishing.repositories.getByName("sonatype")) +if (gradle.startParameter.taskNames.any { it.startsWith("release") }) { + // We apply the 'artifactregistry' plugin conditionally, as it does not support configuration + // cache. + // https://github.com/GoogleCloudPlatform/artifact-registry-maven-tools/issues/85 apply(plugin = "com.google.cloud.artifactregistry.gradle-plugin") } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.maven-publish.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-maven-central.gradle.kts similarity index 86% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.maven-publish.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-maven-central.gradle.kts index c774c604452b..818e6f358a21 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.maven-publish.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-maven-central.gradle.kts @@ -20,6 +20,7 @@ plugins { id("java") id("maven-publish") id("signing") + id("com.hedera.gradle.base.lifecycle") } tasks.withType().configureEach { @@ -53,10 +54,16 @@ val maven = pom { val devGroups = Properties() + val developerProperties = layout.projectDirectory.file("../developers.properties") devGroups.load( providers - .fileContents(layout.projectDirectory.file("../developers.properties")) + .fileContents(developerProperties) .asText + .orElse( + provider { + throw RuntimeException("${developerProperties.asFile} does not exist") + } + ) .get() .reader() ) @@ -84,11 +91,10 @@ val maven = } } - val repoName = isolated.rootProject.name scm { - connection = "scm:git:git://github.com/hashgraph/$repoName.git" - developerConnection = "scm:git:ssh://github.com:hashgraph/$repoName.git" - url = "https://github.com/hashgraph/$repoName" + connection = "scm:git:git://github.com/hashgraph/hedera-services.git" + developerConnection = "scm:git:ssh://github.com:hashgraph/hedera-services.git" + url = "https://github.com/hashgraph/hedera-services" } developers { diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.nexus-publish.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-maven-central.root.gradle.kts similarity index 97% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.nexus-publish.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-maven-central.root.gradle.kts index 429566cb793a..1f7bb5351054 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.nexus-publish.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.publish-maven-central.root.gradle.kts @@ -15,7 +15,7 @@ */ plugins { - id("com.hedera.gradle.lifecycle") + id("com.hedera.gradle.base.lifecycle") id("io.github.gradle-nexus.publish-plugin") } diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.repositories.settings.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.repositories.settings.gradle.kts new file mode 100644 index 000000000000..a2cb30242d57 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.repositories.settings.gradle.kts @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016-2024 Hedera Hashgraph, 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. + */ + +dependencyResolutionManagement { + @Suppress("UnstableApiUsage") + repositories { + maven("https://hyperledger.jfrog.io/artifactory/besu-maven") { + content { includeGroupByRegex("org\\.hyperledger\\..*") } + } + maven("https://artifacts.consensys.net/public/maven/maven/") { + content { includeGroupByRegex("tech\\.pegasys(\\..*)?") } + } + mavenCentral() + maven("https://oss.sonatype.org/content/repositories/snapshots") + } +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.rust.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.rust.gradle.kts new file mode 100644 index 000000000000..94e272352471 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.rust.gradle.kts @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022-2024 Hedera Hashgraph, 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.hedera.gradle.extensions.CargoExtension +import com.hedera.gradle.services.TaskLockService +import com.hedera.gradle.tasks.CargoBuildTask + +plugins { id("java") } + +val cargo = project.extensions.create("cargo") + +cargo.targets( + // "darwin-x86-64", + "darwin-aarch64", + // "linux-x86-64", + // "linux-aarch64", + // "win32-x86-64-msvc", +) + +// Cargo might do installation work, do not run in parallel: +tasks.withType().configureEach { + usesService( + gradle.sharedServices.registerIfAbsent("lock", TaskLockService::class) { + maxParallelUsages = 1 + } + ) +} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-fixtures.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-fixtures.gradle.kts similarity index 100% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-fixtures.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-fixtures.gradle.kts diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-hammer.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-hammer.gradle.kts similarity index 95% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-hammer.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-hammer.gradle.kts index 2d9aaba59527..43eeb3cdc447 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-hammer.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-hammer.gradle.kts @@ -26,15 +26,13 @@ testing.suites { targets.all { testTask { group = "build" + maxHeapSize = "8g" usesService( gradle.sharedServices.registerIfAbsent("lock", TaskLockService::class) { maxParallelUsages = 1 } ) - maxHeapSize = "8g" } } } } - -tasks.assemble { dependsOn(tasks.named("hammerClasses")) } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-time-consuming.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-time-consuming.gradle.kts similarity index 100% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-time-consuming.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-time-consuming.gradle.kts diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-timing-sensitive.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-timing-sensitive.gradle.kts similarity index 100% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.feature.test-timing-sensitive.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test-timing-sensitive.gradle.kts diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test.gradle.kts new file mode 100644 index 000000000000..cc0257f2925b --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.test.gradle.kts @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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.hedera.gradle.services.TaskLockService + +plugins { id("java") } + +@Suppress("UnstableApiUsage") +testing.suites { + named("test") { + useJUnitJupiter() + targets.all { + testTask { + group = "build" + maxHeapSize = "4g" + // Some tests overlap due to using the same temp folders within one project + // maxParallelForks = 4 <- set this, once tests can run in parallel + } + } + } + // remove automatically added compile time dependencies, as we define them explicitly + withType { + configurations.getByName(sources.implementationConfigurationName) { + withDependencies { + removeIf { it.group == "org.junit.jupiter" && it.name == "junit-jupiter" } + } + } + dependencies { runtimeOnly("org.junit.jupiter:junit-jupiter-engine") } + } +} + +// If user gave the argument '-PactiveProcessorCount', then do: +// - run all test tasks in sequence +// - give the -XX:ActiveProcessorCount argument to the test JVMs +val activeProcessorCount = providers.gradleProperty("activeProcessorCount") + +if (activeProcessorCount.isPresent) { + tasks.withType().configureEach { + usesService( + gradle.sharedServices.registerIfAbsent("lock", TaskLockService::class) { + maxParallelUsages = 1 + } + ) + jvmArgs("-XX:ActiveProcessorCount=${activeProcessorCount.get()}") + } +} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.root.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.versioning.gradle.kts similarity index 60% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.root.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.versioning.gradle.kts index a429661c9721..d1a9273f4b43 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.root.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.feature.versioning.gradle.kts @@ -14,33 +14,15 @@ * limitations under the License. */ -import com.hedera.gradle.utils.Utils.generateProjectVersionReport -import com.hedera.gradle.utils.Utils.versionTxt import net.swiftzer.semver.SemVer -plugins { - id("com.hedera.gradle.lifecycle") - id("com.hedera.gradle.repositories") - id("com.hedera.gradle.nexus-publish") - id("com.hedera.gradle.spotless-kotlin") - id("com.hedera.gradle.spotless-markdown") -} - -spotless { - kotlinGradle { target("gradle/plugins/**/*.gradle.kts") } - kotlin { - // For the Kotlin classes (*.kt files) - ktfmt().kotlinlangStyle() - target("gradle/plugins/**/*.kt") - } -} - -val productVersion = layout.projectDirectory.versionTxt().asFile.readText().trim() +plugins { id("com.hedera.gradle.base.version") } tasks.register("githubVersionSummary") { - group = "github" + group = "versioning" - inputs.property("version", productVersion) + inputs.property("productName", project.name) + inputs.property("version", project.version) if (!providers.environmentVariable("GITHUB_STEP_SUMMARY").isPresent) { // Do not throw an exception if running the `gradlew tasks` task @@ -54,9 +36,18 @@ tasks.register("githubVersionSummary") { outputs.file(providers.environmentVariable("GITHUB_STEP_SUMMARY")) doLast { - generateProjectVersionReport( - inputs.properties["version"] as String, - outputs.files.singleFile.outputStream().buffered() + val version = inputs.properties["version"] as String + val productName = inputs.properties["productName"] as String + + outputs.files.singleFile.writeText( + """ + ### Deployed Version Information + + | Artifact Name | Version Number | + | --- | --- | + | $productName | $version | + """ + .trimIndent() ) } } @@ -64,11 +55,13 @@ tasks.register("githubVersionSummary") { tasks.register("showVersion") { group = "versioning" - inputs.property("version", productVersion) + inputs.property("version", project.version) doLast { println(inputs.properties["version"]) } } +val versionTxt = layout.projectDirectory.file("version.txt") + tasks.register("versionAsPrefixedCommit") { group = "versioning" @@ -82,8 +75,8 @@ tasks.register("versionAsPrefixedCommit") { .map { it.trim().substring(0, 7) } ) inputs.property("commitPrefix", providers.gradleProperty("commitPrefix").orElse("adhoc")) - inputs.property("version", productVersion) - outputs.file(layout.projectDirectory.versionTxt()) + inputs.property("version", project.version) + outputs.file(versionTxt) doLast { val newPrerel = @@ -99,8 +92,8 @@ tasks.register("versionAsPrefixedCommit") { tasks.register("versionAsSnapshot") { group = "versioning" - inputs.property("version", productVersion) - outputs.file(layout.projectDirectory.versionTxt()) + inputs.property("version", project.version) + outputs.file(versionTxt) doLast { val currVer = SemVer.parse(inputs.properties["version"] as String) @@ -113,21 +106,15 @@ tasks.register("versionAsSnapshot") { tasks.register("versionAsSpecified") { group = "versioning" - inputs.property("newVersion", providers.gradleProperty("newVersion").orNull) - - if (inputs.properties["newVersion"] == null) { - // Do not throw an exception if running the `gradlew tasks` task - if (project.gradle.startParameter.taskNames.contains("versionAsSpecified")) { - throw IllegalArgumentException( - "No newVersion property provided! " + - "Please add the parameter -PnewVersion= when running this task." - ) - } - } - outputs.file(layout.projectDirectory.versionTxt()) + inputs.property("newVersion", providers.gradleProperty("newVersion")).optional(true) doLast { - val newVer = SemVer.parse(inputs.properties["newVersion"] as String) - outputs.files.singleFile.writeText(newVer.toString()) + val newVer = + inputs.properties["newVersion"] as String? + ?: throw IllegalArgumentException( + "No newVersion property provided! " + + "Please add the parameter -PnewVersion= when running this task." + ) + outputs.files.singleFile.writeText(SemVer.parse(newVer).toString()) } } diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.application.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.module.application.gradle.kts similarity index 54% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.application.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.module.application.gradle.kts index b821df2958c4..199797290421 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.application.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.module.application.gradle.kts @@ -16,34 +16,25 @@ plugins { id("application") - id("com.hedera.gradle.java") + id("jacoco") + id("com.hedera.gradle.base.jpms-modules") + id("com.hedera.gradle.base.lifecycle") + id("com.hedera.gradle.base.version") + id("com.hedera.gradle.check.dependencies") + id("com.hedera.gradle.check.javac-lint") + id("com.hedera.gradle.check.spotless") + id("com.hedera.gradle.check.spotless-java") + id("com.hedera.gradle.check.spotless-kotlin") + id("com.hedera.gradle.feature.git-properties-file") + id("com.hedera.gradle.feature.java-compile") + id("com.hedera.gradle.feature.java-doc") + id("com.hedera.gradle.feature.java-execute") + id("com.hedera.gradle.feature.test") + id("com.hedera.gradle.report.test-logger") } -// Find the central SDK deployment dir by searching up the folder hierarchy -fun sdkDir(dir: Directory): Directory = - if (dir.dir("sdk").asFile.exists()) dir.dir("sdk") else sdkDir(dir.dir("..")) - -// Copy dependencies into `sdk/data/lib` -val copyLib = - tasks.register("copyLib") { - from(project.configurations.runtimeClasspath) - into(sdkDir(layout.projectDirectory).dir("data/lib")) - } - -// Copy built jar into `data/apps` and rename -val copyApp = - tasks.register("copyApp") { - inputs.property("projectName", project.name) - - from(tasks.jar) - into(sdkDir(layout.projectDirectory).dir("data/apps")) - rename { "${inputs.properties["projectName"]}.jar" } - } - -tasks.assemble { - dependsOn(copyLib) - dependsOn(copyApp) -} +// Make the Jar itself executable by setting the 'Main-Class' manifest attribute. +tasks.jar { manifest { attributes("Main-Class" to application.mainClass) } } // The 'application' plugin activates the following tasks as part of 'assemble'. // As we do not use these results right now, disable them: @@ -52,5 +43,3 @@ tasks.startScripts { enabled = false } tasks.distTar { enabled = false } tasks.distZip { enabled = false } - -tasks.jar { manifest { attributes("Main-Class" to application.mainClass) } } diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.module.library.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.module.library.gradle.kts new file mode 100644 index 000000000000..66e9b708b6ac --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.module.library.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022-2024 Hedera Hashgraph, 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. + */ + +plugins { + id("java-library") + id("com.hedera.gradle.feature.publish-maven-central") + id("jacoco") + id("com.hedera.gradle.base.jpms-modules") + id("com.hedera.gradle.base.lifecycle") + id("com.hedera.gradle.base.version") + id("com.hedera.gradle.check.dependencies") + id("com.hedera.gradle.check.javac-lint") + id("com.hedera.gradle.check.spotless") + id("com.hedera.gradle.check.spotless-java") + id("com.hedera.gradle.check.spotless-kotlin") + id("com.hedera.gradle.feature.git-properties-file") + id("com.hedera.gradle.feature.java-compile") + id("com.hedera.gradle.feature.java-doc") + id("com.hedera.gradle.feature.java-execute") + id("com.hedera.gradle.feature.test") + id("com.hedera.gradle.report.test-logger") +} diff --git a/gradle/plugins/src/main/kotlin/com.hedera.gradle.reports.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.code-coverage.gradle.kts similarity index 93% rename from gradle/plugins/src/main/kotlin/com.hedera.gradle.reports.gradle.kts rename to hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.code-coverage.gradle.kts index 74e6fdacebe5..9ca1b722d204 100644 --- a/gradle/plugins/src/main/kotlin/com.hedera.gradle.reports.gradle.kts +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.code-coverage.gradle.kts @@ -15,8 +15,9 @@ */ plugins { - id("com.hedera.gradle.java") + id("java") id("jacoco-report-aggregation") + id("com.hedera.gradle.base.jpms-modules") } // Make aggregation "classpath" use the platform for versions (gradle/versions) diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.develocity.settings.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.develocity.settings.gradle.kts new file mode 100644 index 000000000000..c867e62c8881 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.develocity.settings.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +plugins { id("com.gradle.develocity") } + +develocity { + buildScan { + termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use" + termsOfUseAgree = "yes" + // Enable Gradle Build Scan only with explicit '--scan' + publishing.onlyIf { false } + } +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.test-logger.gradle.kts b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.test-logger.gradle.kts new file mode 100644 index 000000000000..73509ad869f5 --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com.hedera.gradle.report.test-logger.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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.adarshr.gradle.testlogger.theme.ThemeType + +plugins { id("com.adarshr.test-logger") } + +testlogger { + theme = ThemeType.MOCHA_PARALLEL + slowThreshold = 10000 + showPassed = false + showSkipped = false + showStandardStreams = true + showPassedStandardStreams = false + showSkippedStandardStreams = false + showFailedStandardStreams = true +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/extensions/CargoExtension.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/extensions/CargoExtension.kt new file mode 100644 index 000000000000..93539a2ab79f --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/extensions/CargoExtension.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +package com.hedera.gradle.extensions + +import com.hedera.gradle.tasks.CargoBuildTask +import javax.inject.Inject +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.file.ProjectLayout +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.api.tasks.TaskContainer +import org.gradle.kotlin.dsl.register + +// See https://forge.rust-lang.org/platform-support.html. +val toolchains = + listOf( + Toolchain("linux-x86-64", "x86_64-unknown-linux-gnu", "software/linux/amd64"), + Toolchain("linux-aarch64", "aarch64-unknown-linux-gnu", "software/linux/arm64"), + Toolchain("darwin-x86-64", "x86_64-apple-darwin", "software/darwin/amd64"), + Toolchain("darwin-aarch64", "aarch64-apple-darwin", "software/darwin/arm64"), + Toolchain("win32-x86-64-msvc", "x86_64-pc-windows-msvc", "software/windows/amd64") + ) + +data class Toolchain( + @get:Input val platform: String, + @get:Input val target: String, + @get:Input val folder: String +) + +@Suppress("LeakingThis") +abstract class CargoExtension { + abstract val cargoCommand: Property + abstract val rustcCommand: Property + abstract val rustupChannel: Property + abstract val libname: Property + abstract val profile: Property + abstract val verbose: Property + + @get:Inject protected abstract val project: Project + + @get:Inject protected abstract val layout: ProjectLayout + + @get:Inject protected abstract val tasks: TaskContainer + + @get:Inject protected abstract val sourceSets: SourceSetContainer + + init { + cargoCommand.convention(System.getProperty("user.home") + "/.cargo/bin/cargo") + rustcCommand.convention(System.getProperty("user.home") + "/.cargo/bin/rustc") + libname.convention(project.name) + profile.convention("debug") // or "release" + verbose.convention(false) + + // Lifecycle task to only do all carg build tasks (mainly for testing) + project.tasks.register("cargoBuild") { + group = "rust" + description = "Build library (all targets)" + } + } + + fun targets(vararg targetNames: String) { + targetNames.forEach { target -> + val theToolchain = toolchains.find { it.platform == target } + if (theToolchain == null) { + throw GradleException( + "Target $target is not recognized (recognized targets: ${toolchains.map { it.platform }.sorted()})." + ) + } + + val targetBuildTask = + tasks.register( + "cargoBuild${target.replaceFirstChar(Char::titlecase)}" + ) { + group = "rust" + description = "Build library ($target)" + toolchain.set(theToolchain) + sourcesDirectory.set(layout.projectDirectory.dir("src/main/rust")) + destinationDirectory.set( + layout.buildDirectory.dir("rustJniLibs/${theToolchain.platform}") + ) + + cargoToml.set(layout.projectDirectory.file("Cargo.toml")) + cargoCommand.set(this@CargoExtension.cargoCommand) + rustcCommand.set(this@CargoExtension.rustcCommand) + libname.set(this@CargoExtension.libname) + profile.set(this@CargoExtension.profile) + verbose.set(this@CargoExtension.verbose) + rustupChannel.set(this@CargoExtension.rustupChannel) + } + + tasks.named("cargoBuild") { dependsOn(targetBuildTask) } + sourceSets.getByName("main").resources.srcDir(targetBuildTask) + } + } +} diff --git a/gradle/plugins/src/main/kotlin/com/hedera/gradle/services/TaskLockService.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/services/TaskLockService.kt similarity index 100% rename from gradle/plugins/src/main/kotlin/com/hedera/gradle/services/TaskLockService.kt rename to hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/services/TaskLockService.kt diff --git a/gradle/plugins/src/main/kotlin/com/hedera/gradle/spotless/RepairDashedCommentsFormatterStep.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/spotless/RepairDashedCommentsFormatterStep.kt similarity index 100% rename from gradle/plugins/src/main/kotlin/com/hedera/gradle/spotless/RepairDashedCommentsFormatterStep.kt rename to hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/spotless/RepairDashedCommentsFormatterStep.kt diff --git a/gradle/plugins/src/main/kotlin/com/hedera/gradle/spotless/SortModuleInfoRequiresStep.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/spotless/SortModuleInfoRequiresStep.kt similarity index 100% rename from gradle/plugins/src/main/kotlin/com/hedera/gradle/spotless/SortModuleInfoRequiresStep.kt rename to hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/spotless/SortModuleInfoRequiresStep.kt diff --git a/gradle/plugins/src/main/kotlin/com/hedera/gradle/spotless/StripOldLicenseFormatterStep.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/spotless/StripOldLicenseFormatterStep.kt similarity index 100% rename from gradle/plugins/src/main/kotlin/com/hedera/gradle/spotless/StripOldLicenseFormatterStep.kt rename to hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/spotless/StripOldLicenseFormatterStep.kt diff --git a/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/tasks/CargoBuildTask.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/tasks/CargoBuildTask.kt new file mode 100644 index 000000000000..8c7a4a5ad60f --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/tasks/CargoBuildTask.kt @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, 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. + */ + +package com.hedera.gradle.tasks + +import com.hedera.gradle.extensions.Toolchain +import java.io.ByteArrayOutputStream +import java.io.File +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.internal.file.FileOperations +import org.gradle.api.logging.LogLevel +import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations + +@CacheableTask +abstract class CargoBuildTask : DefaultTask() { + + @get:Input abstract val libname: Property + + @get:Input abstract val profile: Property + + @get:Input abstract val verbose: Property + + @get:Input @get:Optional abstract val rustupChannel: Property + + @get:Nested abstract val toolchain: Property + + @get:InputFile + @get:PathSensitive(PathSensitivity.NONE) + abstract val cargoToml: RegularFileProperty + + @get:InputDirectory + @get:PathSensitive(PathSensitivity.NAME_ONLY) + abstract val sourcesDirectory: DirectoryProperty + + @get:OutputDirectory abstract val destinationDirectory: DirectoryProperty + + @get:Internal abstract val rustcCommand: Property + + @get:Internal abstract val cargoCommand: Property + + @get:Inject protected abstract val exec: ExecOperations + + @get:Inject protected abstract val files: FileOperations + + @TaskAction + fun build() { + val defaultTargetTriple = defaultTargetTriple(rustcCommand.get()) + buildProjectForTarget(defaultTargetTriple) + + val cargoOutputDir = + File( + cargoToml.get().asFile.parent, + if (toolchain.get().target == defaultTargetTriple) { + "target/${profile.get()}" + } else { + "target/${toolchain.get().target}/${profile.get()}" + } + ) + + files.copy { + from(cargoOutputDir) + into(destinationDirectory.dir(toolchain.get().folder)) + + include("lib${libname.get()}.so") + include("lib${libname.get()}.dylib") + include("${libname.get()}.dll") + } + } + + private fun buildProjectForTarget(defaultTargetTriple: String) { + exec.exec { + workingDir = cargoToml.get().asFile.parentFile + val theCommandLine = mutableListOf(cargoCommand.get()) + + if (rustupChannel.isPresent) { + val hasPlusSign = rustupChannel.get().startsWith("+") + val maybePlusSign = if (!hasPlusSign) "+" else "" + theCommandLine.add(maybePlusSign + rustupChannel) + } + + theCommandLine.add("build") + + // Respect `verbose` if it is set; otherwise, log if asked to + // with `--info` or `--debug` from the command line. + if (verbose.get() || logger.isEnabled(LogLevel.INFO)) { + theCommandLine.add("--verbose") + } + + if (profile.get() != "debug") { + // Cargo is rigid: it accepts "--release" for release (and + // nothing for dev). This is a cheap way of allowing only + // two values. + theCommandLine.add("--${profile.get()}") + } + if (toolchain.get().target != defaultTargetTriple) { + // Only providing --target for the non-default targets means desktop builds + // can share the build cache with `cargo build`/`cargo test`/etc invocations, + // instead of requiring a large amount of redundant work. + theCommandLine.add("--target=${toolchain.get().target}") + } + commandLine = theCommandLine + } + } + + private fun defaultTargetTriple(rustc: String): String { + val stdout = ByteArrayOutputStream() + exec.exec { + standardOutput = stdout + commandLine = listOf(rustc, "--version", "--verbose") + } + val output = stdout.toString() + + // The `rustc --version --verbose` output contains a number of lines like `key: value`. + // We're only interested in `host: `, which corresponds to the default target triple. + val triplePrefix = "host: " + + val triple = + output + .split("\n") + .find { it.startsWith(triplePrefix) } + ?.substring(triplePrefix.length) + ?.trim() + + if (triple == null) { + throw RuntimeException("Failed to parse `rustc -Vv` output!") + } else { + logger.info("Default rust target triple: $triple") + } + return triple + } +} diff --git a/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/tasks/GitClone.kt b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/tasks/GitClone.kt new file mode 100644 index 000000000000..f70abaad7e2f --- /dev/null +++ b/hedera-gradle-conventions/src/main/kotlin/com/hedera/gradle/tasks/GitClone.kt @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2022-2024 Hedera Hashgraph, 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. + */ + +package com.hedera.gradle.tasks + +import javax.inject.Inject +import org.gradle.StartParameter +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.ProjectLayout +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations + +abstract class GitClone : DefaultTask() { + + @get:Input abstract val url: Property + + @get:Input @get:Optional abstract val tag: Property + + @get:Input @get:Optional abstract val branch: Property + + @get:Input abstract val offline: Property + + @get:OutputDirectory abstract val localCloneDirectory: DirectoryProperty + + @get:Inject protected abstract val exec: ExecOperations + + @get:Inject protected abstract val startParameter: StartParameter + + @get:Inject protected abstract val layout: ProjectLayout + + init { + // If a 'branch' is configured, the task is never up-to-date as it may change + outputs.upToDateWhen { !branch.isPresent } + @Suppress("LeakingThis") + offline = startParameter.isOffline + @Suppress("LeakingThis") + localCloneDirectory = layout.buildDirectory.dir("hedera-protobufs") + } + + @TaskAction + fun cloneOrUpdate() { + if (!tag.isPresent && !branch.isPresent || tag.isPresent && branch.isPresent) { + throw RuntimeException("Define either 'tag' or 'branch'") + } + + val localClone = localCloneDirectory.get() + if (!offline.get()) { + exec.exec { + if (!localClone.dir(".git").asFile.exists()) { + workingDir = localClone.asFile.parentFile + commandLine("git", "clone", url.get(), "-q") + } else { + workingDir = localClone.asFile + commandLine("git", "fetch", "-q") + } + } + } + if (tag.isPresent) { + exec.exec { + workingDir = localClone.asFile + commandLine("git", "checkout", tag.get(), "-q") + } + exec.exec { + workingDir = localClone.asFile + commandLine("git", "reset", "--hard", tag.get(), "-q") + } + } else { + exec.exec { + workingDir = localClone.asFile + commandLine("git", "checkout", branch.get(), "-q") + } + exec.exec { + workingDir = localClone.asFile + commandLine("git", "reset", "--hard", "origin/${branch.get()}", "-q") + } + } + } +} diff --git a/hedera-node/docs/design/services/service-modules.md b/hedera-node/docs/design/services/service-modules.md index bb7be5df64c7..e8230c7440ca 100644 --- a/hedera-node/docs/design/services/service-modules.md +++ b/hedera-node/docs/design/services/service-modules.md @@ -45,7 +45,7 @@ Next to this the `build.gradle.kts` file should look like this: ``` plugins { - id("com.hedera.gradle.services") + id("com.hedera.gradle.module.java-library") } description = "Hedera Foo Service API" @@ -130,7 +130,7 @@ Based on the given definitions and constrains a minimalistic `build.gradle.kts` ``` plugins { - id("com.hedera.gradle.services") + id("com.hedera.gradle.module.java-library") } description = "Default Hedera Foo Service Implementation" diff --git a/hedera-node/hapi-fees/build.gradle.kts b/hedera-node/hapi-fees/build.gradle.kts index 05a8a548c047..b77973f72fe1 100644 --- a/hedera-node/hapi-fees/build.gradle.kts +++ b/hedera-node/hapi-fees/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera Services API Fees" diff --git a/hedera-node/hapi-utils/build.gradle.kts b/hedera-node/hapi-utils/build.gradle.kts index 8efcebff1949..561be653fa85 100644 --- a/hedera-node/hapi-utils/build.gradle.kts +++ b/hedera-node/hapi-utils/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera Services API Utilities" diff --git a/hedera-node/hedera-addressbook-service-impl/build.gradle.kts b/hedera-node/hedera-addressbook-service-impl/build.gradle.kts index f46f5d6533ff..c64e7fb545fd 100644 --- a/hedera-node/hedera-addressbook-service-impl/build.gradle.kts +++ b/hedera-node/hedera-addressbook-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera AddressBook Service Implementation" diff --git a/hedera-node/hedera-addressbook-service/build.gradle.kts b/hedera-node/hedera-addressbook-service/build.gradle.kts index 2d0fd03761ac..d8fc6d11221f 100644 --- a/hedera-node/hedera-addressbook-service/build.gradle.kts +++ b/hedera-node/hedera-addressbook-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera AddressBook Service API" diff --git a/hedera-node/hedera-app-spi/build.gradle.kts b/hedera-node/hedera-app-spi/build.gradle.kts index 743eee16189d..ce74fea1183d 100644 --- a/hedera-node/hedera-app-spi/build.gradle.kts +++ b/hedera-node/hedera-app-spi/build.gradle.kts @@ -15,8 +15,7 @@ */ plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") + id("com.hedera.gradle.module.library") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/hedera-node/hedera-app/build.gradle.kts b/hedera-node/hedera-app/build.gradle.kts index 44776cc290de..9420bdc36509 100644 --- a/hedera-node/hedera-app/build.gradle.kts +++ b/hedera-node/hedera-app/build.gradle.kts @@ -15,8 +15,7 @@ */ plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") + id("com.hedera.gradle.module.library") id("com.hedera.gradle.feature.benchmark") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/hedera-node/hedera-config/build.gradle.kts b/hedera-node/hedera-config/build.gradle.kts index 7485155dc32f..bf1b7aec0749 100644 --- a/hedera-node/hedera-config/build.gradle.kts +++ b/hedera-node/hedera-config/build.gradle.kts @@ -15,8 +15,7 @@ */ plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") + id("com.hedera.gradle.module.library") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/hedera-node/hedera-consensus-service-impl/build.gradle.kts b/hedera-node/hedera-consensus-service-impl/build.gradle.kts index 67f55402d6f2..7619a538e16f 100644 --- a/hedera-node/hedera-consensus-service-impl/build.gradle.kts +++ b/hedera-node/hedera-consensus-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera Consensus Service Implementation" diff --git a/hedera-node/hedera-consensus-service/build.gradle.kts b/hedera-node/hedera-consensus-service/build.gradle.kts index 04a3aa43ffc0..f549f469cfa7 100644 --- a/hedera-node/hedera-consensus-service/build.gradle.kts +++ b/hedera-node/hedera-consensus-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera Consensus Service API" diff --git a/hedera-node/hedera-file-service-impl/build.gradle.kts b/hedera-node/hedera-file-service-impl/build.gradle.kts index 0eeaea14bdac..19efacc12dbc 100644 --- a/hedera-node/hedera-file-service-impl/build.gradle.kts +++ b/hedera-node/hedera-file-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera File Service Implementation" diff --git a/hedera-node/hedera-file-service/build.gradle.kts b/hedera-node/hedera-file-service/build.gradle.kts index 8a4a2c69c71a..c768538239c3 100644 --- a/hedera-node/hedera-file-service/build.gradle.kts +++ b/hedera-node/hedera-file-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera File Service API" diff --git a/hedera-node/hedera-network-admin-service-impl/build.gradle.kts b/hedera-node/hedera-network-admin-service-impl/build.gradle.kts index 07590e13359a..b54a806c9d6a 100644 --- a/hedera-node/hedera-network-admin-service-impl/build.gradle.kts +++ b/hedera-node/hedera-network-admin-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera Network Admin Service Implementation" diff --git a/hedera-node/hedera-network-admin-service/build.gradle.kts b/hedera-node/hedera-network-admin-service/build.gradle.kts index e4844ed09c55..6292ce87f70c 100644 --- a/hedera-node/hedera-network-admin-service/build.gradle.kts +++ b/hedera-node/hedera-network-admin-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera NetworkAdmin Service API" diff --git a/hedera-node/hedera-schedule-service-impl/build.gradle.kts b/hedera-node/hedera-schedule-service-impl/build.gradle.kts index 149f263fe93f..0ba441733379 100644 --- a/hedera-node/hedera-schedule-service-impl/build.gradle.kts +++ b/hedera-node/hedera-schedule-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera Schedule Service Implementation" diff --git a/hedera-node/hedera-schedule-service/build.gradle.kts b/hedera-node/hedera-schedule-service/build.gradle.kts index b187f3d2a100..4ab98924d2d0 100644 --- a/hedera-node/hedera-schedule-service/build.gradle.kts +++ b/hedera-node/hedera-schedule-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera Schedule Service API" diff --git a/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts b/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts index 694111ddf40e..cfbc97b7ee17 100644 --- a/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts +++ b/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera Smart Contract Service Implementation" diff --git a/hedera-node/hedera-smart-contract-service/build.gradle.kts b/hedera-node/hedera-smart-contract-service/build.gradle.kts index d855b687dbf0..6c638ddf93b7 100644 --- a/hedera-node/hedera-smart-contract-service/build.gradle.kts +++ b/hedera-node/hedera-smart-contract-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera Smart Contract Service API" diff --git a/hedera-node/hedera-token-service-impl/build.gradle.kts b/hedera-node/hedera-token-service-impl/build.gradle.kts index 037f96c17053..5a416a0bc5fc 100644 --- a/hedera-node/hedera-token-service-impl/build.gradle.kts +++ b/hedera-node/hedera-token-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera Token Service Implementation" diff --git a/hedera-node/hedera-token-service/build.gradle.kts b/hedera-node/hedera-token-service/build.gradle.kts index d6c299811c32..ae113cac303b 100644 --- a/hedera-node/hedera-token-service/build.gradle.kts +++ b/hedera-node/hedera-token-service/build.gradle.kts @@ -15,8 +15,7 @@ */ plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") + id("com.hedera.gradle.module.library") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/hedera-node/hedera-util-service-impl/build.gradle.kts b/hedera-node/hedera-util-service-impl/build.gradle.kts index e76f4f360ac1..246b9ad5b92c 100644 --- a/hedera-node/hedera-util-service-impl/build.gradle.kts +++ b/hedera-node/hedera-util-service-impl/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Default Hedera Util Service Implementation" diff --git a/hedera-node/hedera-util-service/build.gradle.kts b/hedera-node/hedera-util-service/build.gradle.kts index 3ce441d52601..5c90638c8177 100644 --- a/hedera-node/hedera-util-service/build.gradle.kts +++ b/hedera-node/hedera-util-service/build.gradle.kts @@ -14,10 +14,7 @@ * limitations under the License. */ -plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.services-publish") -} +plugins { id("com.hedera.gradle.module.library") } description = "Hedera Util Service API" diff --git a/hedera-node/test-clients/build.gradle.kts b/hedera-node/test-clients/build.gradle.kts index d10768c26e2e..2cd734e31c32 100644 --- a/hedera-node/test-clients/build.gradle.kts +++ b/hedera-node/test-clients/build.gradle.kts @@ -14,11 +14,12 @@ * limitations under the License. */ +import com.github.jengelman.gradle.plugins.shadow.internal.DefaultDependencyFilter import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { - id("com.hedera.gradle.services") - id("com.hedera.gradle.shadow-jar") + id("com.hedera.gradle.module.application") + id("com.gradleup.shadow") version "8.3.0" } description = "Hedera Services Test Clients for End to End Tests (EET)" @@ -35,6 +36,8 @@ sourceSets { create("yahcli") } +tasks.withType().configureEach { options.compilerArgs.add("-Xlint:-exports") } + tasks.register("runTestClient") { group = "build" description = "Run a test client via -PtestClient=" @@ -234,17 +237,23 @@ tasks.register("testRepeatable") { modularity.inferModulePath.set(false) } -tasks.shadowJar { - archiveFileName.set("SuiteRunner.jar") +tasks.withType().configureEach { + group = "shadow" + from(sourceSets.main.get().output) + mergeServiceFiles() - manifest { - attributes( - "Main-Class" to "com.hedera.services.bdd.suites.SuiteRunner", - "Multi-Release" to "true" - ) - } + manifest { attributes("Multi-Release" to "true") } + + // There is an issue in the shadow plugin that it automatically accesses the + // files in 'runtimeClasspath' while Gradle is building the task graph. + // See: https://github.com/GradleUp/shadow/issues/882 + dependencyFilter = NoResolveDependencyFilter() } +application.mainClass = "com.hedera.services.bdd.suites.SuiteRunner" + +tasks.shadowJar { archiveFileName.set("SuiteRunner.jar") } + val yahCliJar = tasks.register("yahCliJar") { exclude(listOf("META-INF/*.DSA", "META-INF/*.RSA", "META-INF/*.SF", "META-INF/INDEX.LIST")) @@ -252,12 +261,7 @@ val yahCliJar = archiveClassifier.set("yahcli") configurations = listOf(project.configurations.getByName("yahcliRuntimeClasspath")) - manifest { - attributes( - "Main-Class" to "com.hedera.services.yahcli.Yahcli", - "Multi-Release" to "true" - ) - } + manifest { attributes("Main-Class" to "com.hedera.services.yahcli.Yahcli") } } val rcdiffJar = @@ -269,12 +273,7 @@ val rcdiffJar = archiveFileName.set("rcdiff.jar") configurations = listOf(project.configurations.getByName("rcdiffRuntimeClasspath")) - manifest { - attributes( - "Main-Class" to "com.hedera.services.rcdiff.RcDiffCmdWrapper", - "Multi-Release" to "true" - ) - } + manifest { attributes("Main-Class" to "com.hedera.services.rcdiff.RcDiffCmdWrapper") } } val validationJar = @@ -286,8 +285,7 @@ val validationJar = manifest { attributes( "Main-Class" to - "com.hedera.services.bdd.suites.utils.validation.ValidationScenarios", - "Multi-Release" to "true" + "com.hedera.services.bdd.suites.utils.validation.ValidationScenarios" ) } } @@ -323,3 +321,9 @@ tasks.clean { dependsOn(cleanYahCli) dependsOn(cleanValidation) } + +class NoResolveDependencyFilter : DefaultDependencyFilter(project) { + override fun resolve(configuration: FileCollection): FileCollection { + return configuration + } +} diff --git a/hedera-node/test-clients/src/main/java/module-info.java b/hedera-node/test-clients/src/main/java/module-info.java index 6abd193c05a3..e15116107ed1 100644 --- a/hedera-node/test-clients/src/main/java/module-info.java +++ b/hedera-node/test-clients/src/main/java/module-info.java @@ -62,30 +62,8 @@ exports com.hedera.services.bdd.junit.support.validators.block; exports com.hedera.services.bdd.utils; - requires transitive com.hedera.node.app.hapi.fees; - requires transitive com.hedera.node.app.hapi.utils; - requires transitive com.hedera.node.app.test.fixtures; - requires transitive com.hedera.node.app; - requires transitive com.hedera.node.config; - requires transitive com.hedera.node.hapi; - requires transitive com.swirlds.base; - requires transitive com.swirlds.common; - requires transitive com.swirlds.config.api; - requires transitive com.swirlds.metrics.api; - requires transitive com.swirlds.platform.core; - requires transitive com.swirlds.state.api; - requires transitive com.fasterxml.jackson.annotation; - requires transitive com.google.common; - requires transitive com.google.protobuf; - requires transitive headlong; - requires transitive io.grpc; - requires transitive net.i2p.crypto.eddsa; - requires transitive org.apache.commons.io; - requires transitive org.apache.logging.log4j; - requires transitive org.junit.jupiter.api; - requires transitive org.junit.platform.launcher; - requires transitive org.testcontainers; - requires transitive tuweni.bytes; + requires com.hedera.node.app.hapi.fees; + requires com.hedera.node.app.hapi.utils; requires com.hedera.node.app.service.addressbook.impl; requires com.hedera.node.app.service.addressbook; requires com.hedera.node.app.service.consensus.impl; @@ -97,29 +75,51 @@ requires com.hedera.node.app.service.token; requires com.hedera.node.app.service.util.impl; requires com.hedera.node.app.spi; + requires com.hedera.node.app.test.fixtures; + requires com.hedera.node.app; + requires com.hedera.node.config; + requires com.hedera.node.hapi; requires com.swirlds.base.test.fixtures; + requires com.swirlds.base; + requires com.swirlds.common; + requires com.swirlds.config.api; requires com.swirlds.config.extensions.test.fixtures; + requires com.swirlds.metrics.api; requires com.swirlds.platform.core.test.fixtures; + requires com.swirlds.platform.core; + requires com.swirlds.state.api; + requires com.fasterxml.jackson.annotation; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; requires com.github.dockerjava.api; + requires com.google.common; + requires com.google.protobuf; requires com.sun.jna; + requires headlong; requires io.grpc.netty; requires io.grpc.stub; + requires io.grpc; requires io.netty.handler; requires java.desktop; requires java.net.http; + requires net.i2p.crypto.eddsa; + requires org.apache.commons.io; requires org.apache.commons.lang3; requires org.apache.logging.log4j.core; + requires org.apache.logging.log4j; requires org.assertj.core; requires org.bouncycastle.provider; requires org.hyperledger.besu.datatypes; requires org.hyperledger.besu.internal.crypto; requires org.hyperledger.besu.nativelib.secp256k1; requires org.json; + requires org.junit.jupiter.api; requires org.junit.platform.commons; + requires org.junit.platform.launcher; requires org.opentest4j; + requires org.testcontainers; requires org.yaml.snakeyaml; + requires tuweni.bytes; requires tuweni.units; requires static com.github.spotbugs.annotations; requires static com.hedera.pbj.runtime; diff --git a/hedera-node/test-clients/src/yahcli/java/module-info.java b/hedera-node/test-clients/src/yahcli/java/module-info.java index c0e5cc0e5bd3..be9118c3c2ad 100644 --- a/hedera-node/test-clients/src/yahcli/java/module-info.java +++ b/hedera-node/test-clients/src/yahcli/java/module-info.java @@ -7,6 +7,7 @@ requires com.swirlds.common; requires com.github.spotbugs.annotations; requires com.google.common; + requires com.google.protobuf; requires info.picocli; requires net.i2p.crypto.eddsa; requires org.apache.logging.log4j; diff --git a/platform-sdk/build.gradle.kts b/platform-sdk/build.gradle.kts index c88872a30022..fb17df592521 100644 --- a/platform-sdk/build.gradle.kts +++ b/platform-sdk/build.gradle.kts @@ -14,25 +14,19 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.java") } +plugins { id("com.hedera.gradle.module.application") } val sdkDir = layout.projectDirectory.dir("sdk") -tasks.register("run") { - group = "application" +tasks.named("run") { workingDir = sdkDir.asFile - mainClass.set("com.swirlds.platform.Browser") + mainClass = "com.swirlds.platform.Browser" classpath = sdkDir.asFileTree.matching { include("*.jar") } jvmArgs = listOf("-agentlib:jdwp=transport=dt_socket,address=8888,server=y,suspend=n") maxHeapSize = "8g" - // Running ':assemble' of all 'platform-sdk' subprojects before, will trigger - // copyLib/copyApp, of all projects that provide an application. - dependsOn( - rootProject.subprojects - .filter { it.projectDir.absolutePath.contains("/platform-sdk/") } - .map { "${it.path}:assemble" } - ) + // Build everything for the 'sdk' folder + dependsOn(":swirlds:assemble") } val cleanRun = diff --git a/platform-sdk/platform-apps/demos/CryptocurrencyDemo/build.gradle.kts b/platform-sdk/platform-apps/demos/CryptocurrencyDemo/build.gradle.kts index 96c6c136e38b..94b9d5e07cd2 100644 --- a/platform-sdk/platform-apps/demos/CryptocurrencyDemo/build.gradle.kts +++ b/platform-sdk/platform-apps/demos/CryptocurrencyDemo/build.gradle.kts @@ -14,6 +14,6 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.crypto.CryptocurrencyDemoMain") +application.mainClass = "com.swirlds.demo.crypto.CryptocurrencyDemoMain" diff --git a/platform-sdk/platform-apps/demos/HelloSwirldDemo/build.gradle.kts b/platform-sdk/platform-apps/demos/HelloSwirldDemo/build.gradle.kts index 076aa930d40c..c41624f102c0 100644 --- a/platform-sdk/platform-apps/demos/HelloSwirldDemo/build.gradle.kts +++ b/platform-sdk/platform-apps/demos/HelloSwirldDemo/build.gradle.kts @@ -14,6 +14,6 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.hello.HelloSwirldDemoMain") +application.mainClass = "com.swirlds.demo.hello.HelloSwirldDemoMain" diff --git a/platform-sdk/platform-apps/demos/StatsDemo/build.gradle.kts b/platform-sdk/platform-apps/demos/StatsDemo/build.gradle.kts index 2a6bd33eb2c3..829bce469410 100644 --- a/platform-sdk/platform-apps/demos/StatsDemo/build.gradle.kts +++ b/platform-sdk/platform-apps/demos/StatsDemo/build.gradle.kts @@ -14,6 +14,6 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.stats.StatsDemoMain") +application.mainClass = "com.swirlds.demo.stats.StatsDemoMain" diff --git a/platform-sdk/platform-apps/tests/AddressBookTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/AddressBookTestingTool/build.gradle.kts index 6bb16a68e867..4104e6aedf7e 100644 --- a/platform-sdk/platform-apps/tests/AddressBookTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/AddressBookTestingTool/build.gradle.kts @@ -14,6 +14,6 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.addressbook.AddressBookTestingToolMain") +application.mainClass = "com.swirlds.demo.addressbook.AddressBookTestingToolMain" diff --git a/platform-sdk/platform-apps/tests/ConsistencyTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/ConsistencyTestingTool/build.gradle.kts index 75324db7df15..3ecb040eba07 100644 --- a/platform-sdk/platform-apps/tests/ConsistencyTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/ConsistencyTestingTool/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.consistency.ConsistencyTestingToolMain") +application.mainClass = "com.swirlds.demo.consistency.ConsistencyTestingToolMain" mainModuleInfo { annotationProcessor("com.swirlds.config.processor") } diff --git a/platform-sdk/platform-apps/tests/ISSTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/ISSTestingTool/build.gradle.kts index 0ccf911efacb..d97cd0394f75 100644 --- a/platform-sdk/platform-apps/tests/ISSTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/ISSTestingTool/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.iss.ISSTestingToolMain") +application.mainClass = "com.swirlds.demo.iss.ISSTestingToolMain" mainModuleInfo { annotationProcessor("com.swirlds.config.processor") } diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts index faf0295e6b51..d098934e5a56 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.migration.MigrationTestingToolMain") +application.mainClass = "com.swirlds.demo.migration.MigrationTestingToolMain" testModuleInfo { requires("org.junit.jupiter.api") diff --git a/platform-sdk/platform-apps/tests/PlatformTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/PlatformTestingTool/build.gradle.kts index 5eddb4203445..0b5ec6afcc2e 100644 --- a/platform-sdk/platform-apps/tests/PlatformTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/PlatformTestingTool/build.gradle.kts @@ -15,8 +15,9 @@ */ plugins { - id("com.hedera.gradle.application") + id("com.hedera.gradle.module.application") id("com.hedera.gradle.feature.test-timing-sensitive") + id("com.google.protobuf") } diff --git a/platform-sdk/platform-apps/tests/StatsSigningTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/StatsSigningTestingTool/build.gradle.kts index 110a05eb2d7a..d283585ee000 100644 --- a/platform-sdk/platform-apps/tests/StatsSigningTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/StatsSigningTestingTool/build.gradle.kts @@ -14,10 +14,10 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } // Remove the following line to enable all 'javac' lint checks that we have turned on by default // and then fix the reported issues. tasks.withType().configureEach { options.compilerArgs.add("-Xlint:-cast") } -application.mainClass.set("com.swirlds.demo.stats.signing.StatsSigningTestingToolMain") +application.mainClass = "com.swirlds.demo.stats.signing.StatsSigningTestingToolMain" diff --git a/platform-sdk/platform-apps/tests/StressTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/StressTestingTool/build.gradle.kts index 780a202ff27d..245bb522da26 100644 --- a/platform-sdk/platform-apps/tests/StressTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/StressTestingTool/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } -application.mainClass.set("com.swirlds.demo.stress.StressTestingToolMain") +application.mainClass = "com.swirlds.demo.stress.StressTestingToolMain" mainModuleInfo { annotationProcessor("com.swirlds.config.processor") } diff --git a/platform-sdk/swirlds-base/build.gradle.kts b/platform-sdk/swirlds-base/build.gradle.kts index 91078842e575..669fd932c662 100644 --- a/platform-sdk/swirlds-base/build.gradle.kts +++ b/platform-sdk/swirlds-base/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.benchmark") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-timing-sensitive") diff --git a/platform-sdk/swirlds-benchmarks/build.gradle.kts b/platform-sdk/swirlds-benchmarks/build.gradle.kts index 28429d4ebed1..95da3fbbac5e 100644 --- a/platform-sdk/swirlds-benchmarks/build.gradle.kts +++ b/platform-sdk/swirlds-benchmarks/build.gradle.kts @@ -17,7 +17,7 @@ import me.champeau.jmh.JMHTask plugins { - id("com.hedera.gradle.platform") + id("com.hedera.gradle.module.application") id("com.hedera.gradle.feature.benchmark") } diff --git a/platform-sdk/swirlds-cli/build.gradle.kts b/platform-sdk/swirlds-cli/build.gradle.kts index 6daacca0a6da..6584e4dc3e05 100644 --- a/platform-sdk/swirlds-cli/build.gradle.kts +++ b/platform-sdk/swirlds-cli/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } testModuleInfo { requires("org.junit.jupiter.api") } diff --git a/platform-sdk/swirlds-common/build.gradle.kts b/platform-sdk/swirlds-common/build.gradle.kts index 7a3984f114ef..68951e5ab07f 100644 --- a/platform-sdk/swirlds-common/build.gradle.kts +++ b/platform-sdk/swirlds-common/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-timing-sensitive") } diff --git a/platform-sdk/swirlds-config-api/build.gradle.kts b/platform-sdk/swirlds-config-api/build.gradle.kts index 673cff9e1397..ab620bf7f260 100644 --- a/platform-sdk/swirlds-config-api/build.gradle.kts +++ b/platform-sdk/swirlds-config-api/build.gradle.kts @@ -15,7 +15,7 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/platform-sdk/swirlds-config-extensions/build.gradle.kts b/platform-sdk/swirlds-config-extensions/build.gradle.kts index f11a3d013c15..203e8bfe2273 100644 --- a/platform-sdk/swirlds-config-extensions/build.gradle.kts +++ b/platform-sdk/swirlds-config-extensions/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/platform-sdk/swirlds-config-impl/build.gradle.kts b/platform-sdk/swirlds-config-impl/build.gradle.kts index f296d4524572..8b42bf509a3e 100644 --- a/platform-sdk/swirlds-config-impl/build.gradle.kts +++ b/platform-sdk/swirlds-config-impl/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.benchmark") } diff --git a/platform-sdk/swirlds-config-processor/build.gradle.kts b/platform-sdk/swirlds-config-processor/build.gradle.kts index 19b3d4822b37..428898be4dac 100644 --- a/platform-sdk/swirlds-config-processor/build.gradle.kts +++ b/platform-sdk/swirlds-config-processor/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } mainModuleInfo { annotationProcessor("com.google.auto.service.processor") } diff --git a/platform-sdk/swirlds-fchashmap/build.gradle.kts b/platform-sdk/swirlds-fchashmap/build.gradle.kts index 2ea867132dcc..a60f9b20c4e4 100644 --- a/platform-sdk/swirlds-fchashmap/build.gradle.kts +++ b/platform-sdk/swirlds-fchashmap/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } mainModuleInfo { annotationProcessor("com.swirlds.config.processor") } diff --git a/platform-sdk/swirlds-fcqueue/build.gradle.kts b/platform-sdk/swirlds-fcqueue/build.gradle.kts index e1675a00ef13..b1c89efe0869 100644 --- a/platform-sdk/swirlds-fcqueue/build.gradle.kts +++ b/platform-sdk/swirlds-fcqueue/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } testModuleInfo { diff --git a/platform-sdk/swirlds-logging-log4j-appender/build.gradle.kts b/platform-sdk/swirlds-logging-log4j-appender/build.gradle.kts index 6c7b688ba995..c6fcd3d1bc14 100644 --- a/platform-sdk/swirlds-logging-log4j-appender/build.gradle.kts +++ b/platform-sdk/swirlds-logging-log4j-appender/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } mainModuleInfo { diff --git a/platform-sdk/swirlds-logging/build.gradle.kts b/platform-sdk/swirlds-logging/build.gradle.kts index fdaa4647d989..4f990f4ecd9a 100644 --- a/platform-sdk/swirlds-logging/build.gradle.kts +++ b/platform-sdk/swirlds-logging/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.benchmark") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-time-consuming") diff --git a/platform-sdk/swirlds-merkle/build.gradle.kts b/platform-sdk/swirlds-merkle/build.gradle.kts index 5db6bc803b11..1c52e60179d7 100644 --- a/platform-sdk/swirlds-merkle/build.gradle.kts +++ b/platform-sdk/swirlds-merkle/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-timing-sensitive") } diff --git a/platform-sdk/swirlds-merkledb/build.gradle.kts b/platform-sdk/swirlds-merkledb/build.gradle.kts index 1c613517ef36..63da3f6e5428 100644 --- a/platform-sdk/swirlds-merkledb/build.gradle.kts +++ b/platform-sdk/swirlds-merkledb/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.benchmark") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-hammer") diff --git a/platform-sdk/swirlds-metrics-api/build.gradle.kts b/platform-sdk/swirlds-metrics-api/build.gradle.kts index 278ebab31a3a..49ce57e583d9 100644 --- a/platform-sdk/swirlds-metrics-api/build.gradle.kts +++ b/platform-sdk/swirlds-metrics-api/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } testModuleInfo { diff --git a/platform-sdk/swirlds-metrics-impl/build.gradle.kts b/platform-sdk/swirlds-metrics-impl/build.gradle.kts index 278ebab31a3a..49ce57e583d9 100644 --- a/platform-sdk/swirlds-metrics-impl/build.gradle.kts +++ b/platform-sdk/swirlds-metrics-impl/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") } testModuleInfo { diff --git a/platform-sdk/swirlds-platform-core/build.gradle.kts b/platform-sdk/swirlds-platform-core/build.gradle.kts index 0d9d9c8528ad..9fd0c14ef06e 100644 --- a/platform-sdk/swirlds-platform-core/build.gradle.kts +++ b/platform-sdk/swirlds-platform-core/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.benchmark") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-timing-sensitive") diff --git a/platform-sdk/swirlds-state-api/build.gradle.kts b/platform-sdk/swirlds-state-api/build.gradle.kts index 3a3e781966ee..fb1a770e3803 100644 --- a/platform-sdk/swirlds-state-api/build.gradle.kts +++ b/platform-sdk/swirlds-state-api/build.gradle.kts @@ -15,8 +15,8 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.test-fixtures") } diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/build.gradle.kts b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/build.gradle.kts index 6df6656b684e..cd4bd2bfbc73 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/build.gradle.kts +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/build.gradle.kts @@ -15,8 +15,21 @@ */ plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.feature.benchmark") + id("java-library") + id("jacoco") + id("com.hedera.gradle.base.jpms-modules") + id("com.hedera.gradle.base.lifecycle") + id("com.hedera.gradle.base.version") + id("com.hedera.gradle.check.dependencies") + id("com.hedera.gradle.check.spotless") + id("com.hedera.gradle.check.spotless-java") + id("com.hedera.gradle.check.spotless-kotlin") + id("com.hedera.gradle.feature.git-properties-file") + id("com.hedera.gradle.feature.java-compile") + id("com.hedera.gradle.feature.java-doc") + id("com.hedera.gradle.feature.java-execute") + id("com.hedera.gradle.feature.test") + id("com.hedera.gradle.report.test-logger") } // Remove the following line to enable all 'javac' lint checks that we have turned on by default diff --git a/platform-sdk/swirlds-virtualmap/build.gradle.kts b/platform-sdk/swirlds-virtualmap/build.gradle.kts index f905ad12214b..f2b7b83bfd0e 100644 --- a/platform-sdk/swirlds-virtualmap/build.gradle.kts +++ b/platform-sdk/swirlds-virtualmap/build.gradle.kts @@ -17,8 +17,8 @@ import me.champeau.jmh.JMHTask plugins { - id("com.hedera.gradle.platform") - id("com.hedera.gradle.platform-publish") + id("com.hedera.gradle.module.library") + id("com.hedera.gradle.feature.publish-artifactregistry") id("com.hedera.gradle.feature.benchmark") id("com.hedera.gradle.feature.test-fixtures") id("com.hedera.gradle.feature.test-hammer") diff --git a/platform-sdk/swirlds/build.gradle.kts b/platform-sdk/swirlds/build.gradle.kts index f2726a41736f..08f9b63db5a2 100644 --- a/platform-sdk/swirlds/build.gradle.kts +++ b/platform-sdk/swirlds/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("com.hedera.gradle.application") } +plugins { id("com.hedera.gradle.module.application") } mainModuleInfo { runtimeOnly("com.swirlds.platform.core") @@ -24,16 +24,12 @@ mainModuleInfo { application.mainClass.set("com.swirlds.platform.Browser") -tasks.copyApp { - // Adjust configuration from 'com.hedera.hashgraph.application': - // Copy directly into 'sdk' and not 'sdk/data/apps' - into(layout.projectDirectory.dir("../sdk")) -} - tasks.jar { // Gradle fails to track 'configurations.runtimeClasspath' as an input to the task if it is // only used in the 'manifest.attributes'. Hence, we explicitly add it as input. inputs.files(configurations.runtimeClasspath) + + archiveVersion.convention(null as String?) doFirst { manifest { attributes( @@ -47,3 +43,55 @@ tasks.jar { } } } + +// Copy this app () and the demo apps into 'sdk' folder +val demoApp = configurations.dependencyScope("demoApp") + +dependencies { + demoApp(project(":AddressBookTestingTool")) + demoApp(project(":ConsistencyTestingTool")) + demoApp(project(":CryptocurrencyDemo")) + demoApp(project(":HelloSwirldDemo")) + demoApp(project(":ISSTestingTool")) + demoApp(project(":MigrationTestingTool")) + demoApp(project(":PlatformTestingTool")) + demoApp(project(":StatsDemo")) + demoApp(project(":StatsSigningTestingTool")) + demoApp(project(":StressTestingTool")) +} + +val demoAppsRuntimeClasspath = + configurations.resolvable("demoAppsRuntimeClasspath") { + extendsFrom(demoApp.get()) + shouldResolveConsistentlyWith(configurations.mainRuntimeClasspath.get()) + attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) + attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attributes.attribute( + LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, + objects.named(LibraryElements.JAR) + ) + attributes.attribute(Attribute.of("javaModule", Boolean::class.javaObjectType), true) + } +val demoAppsJars = + configurations.resolvable("demoAppsJars") { + extendsFrom(demoApp.get(), configurations.internal.get()) + attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) + isTransitive = false // only the application Jars, not the dependencies + } + +tasks.register("copyApps") { + destinationDir = layout.projectDirectory.dir("../sdk").asFile + from(tasks.jar) // 'swirlds.jar' goes in directly into 'sdk' + into("data/apps") { + // Copy built jar into `data/apps` and rename + from(demoAppsJars) + rename { "${it.substring(0, it.indexOf("-"))}.jar" } + } + into("data/lib") { + // Copy dependencies into `sdk/data/lib` + from(project.configurations.runtimeClasspath) + from(demoAppsRuntimeClasspath.get().minus(demoAppsJars.get())) + } +} + +tasks.assemble { dependsOn(tasks.named("copyApps")) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 83f80f05bf1e..236ca6a5966b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ -pluginManagement { includeBuild("gradle/plugins") } +pluginManagement { includeBuild("hedera-gradle-conventions") } // TO BE REMOVED -plugins { id("com.hedera.gradle.settings") } +plugins { id("com.hedera.gradle.build") version "0.1.0" } javaModules { // This "intermediate parent project" should be removed