import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.time.Duration plugins { alias(libs.plugins.spotless) alias(libs.plugins.docker) } task compileAll // to allow to have unused vars/imports,etc for faster debugging/prototyping // instead of deleting and re-adding code all the time def allowCompilationWarnings = System.getenv('LINEA_DEV_ALLOW_WARNINGS') != null allprojects { repositories { mavenCentral() mavenLocal() } apply plugin: 'java' // do not add kotlin plugin here, it will add unnecessary Kotlin runtime dependencies apply plugin: 'jacoco' tasks.withType(KotlinCompile).configureEach { compileAll.dependsOn it compilerOptions { allWarningsAsErrors = !allowCompilationWarnings } } tasks.withType(JavaCompile).configureEach { compileAll.dependsOn it options.encoding = 'UTF-8' options.deprecation = true options.compilerArgs.addAll([ '-parameters', '-Xlint:cast', '-Xlint:overloads', '-Xlint:divzero', '-Xlint:finally', '-Xlint:static', '-Xlint:deprecation', ]) if (!allowCompilationWarnings) { options.compilerArgs.addAll(['-Werror']) } if (!project.path.contains("testing-tools")) { // testing tools have 100+ errors because of this // skipping them for now options.compilerArgs.addAll(['-Xlint:rawtypes']) } } jacoco { toolVersion = '0.8.11' if (project.tasks.findByName('integrationTest')) { applyTo integrationTest } if (project.tasks.findByName('acceptanceTest')) { applyTo acceptanceTest } } jacocoTestReport { dependsOn test } tasks.withType(Test).configureEach { testLogging { events = [ //TestLogEvent.STARTED, //TestLogEvent.PASSED, TestLogEvent.FAILED, TestLogEvent.SKIPPED, TestLogEvent.STANDARD_ERROR ] exceptionFormat TestExceptionFormat.FULL showCauses true showExceptions true showStackTraces true // set showStandardStreams if you need to see test logs showStandardStreams false } systemProperty("L1_RPC_URL", "http://localhost:8445") systemProperty("L2_RPC_URL", "http://localhost:8545") systemProperty("L1_GENESIS", "docker/config/l1-node/el/genesis.json") systemProperty("L2_GENESIS", "docker/config/linea-local-dev-genesis-PoA-besu.json") systemProperties["junit.jupiter.execution.timeout.default"] = "5 m" // 5 minutes systemProperties["junit.jupiter.execution.parallel.enabled"] = true systemProperties["junit.jupiter.execution.parallel.mode.default"] = "concurrent" systemProperties["junit.jupiter.execution.parallel.mode.classes.default"] = "concurrent" maxParallelForks = Math.max(Runtime.runtime.availableProcessors(), 9) } tasks.withType(Test).matching { it.name == 'integrationTest' }.configureEach { outputs.cacheIf { false } outputs.upToDateWhen { false } } afterEvaluate { subproject -> if (hasJavaOrKotlinPlugins(subproject)) { subproject.apply plugin: 'com.diffplug.spotless' subproject.spotless { if (hasKotlinPlugin(subproject)) { kotlin { // by default the target is every '.kt' and '.kts` file in the java sourcesets //ktfmt() ktlint(libs.versions.ktlint.get().toString()).setEditorConfigPath("$rootDir/.editorconfig") } } // spotless check applied to build.gradle (groovy) files groovyGradle { target '*.gradle' greclipse() indentWithSpaces(2) endWithNewline() } java { target 'src/**/*.java' // Do not use 'targetExclude' with wildcard patterns, it will add minutes to the build removeUnusedImports() trimTrailingWhitespace() endWithNewline() googleJavaFormat(libs.versions.googleJavaFormat.get()) } } } } } task jacocoRootReport(type: JacocoReport) { additionalSourceDirs.from files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.from files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.from files(subprojects.sourceSets.main.output) executionData.from fileTree(dir: '.', includes: ['**/jacoco/*.exec']) reports { xml.required = true // xml.enabled = true FIXME: deprecated, breaking latest versions of gradle. csv.required = true html.destination file("build/reports/jacocoHtml") } onlyIf = { true } } dockerCompose { localStack { startedServices = [ "postgres", "sequencer", "l1-node-genesis-generator", "l1-el-node", "l1-cl-node", // For debug // "l1-blockscout", // "l2-blockscout" ] composeAdditionalArgs = [ "--profile", "l1", "--profile", "l2" ] useComposeFiles = [ "${project.rootDir.path}/docker/compose-tracing-v2.yml" ] waitForHealthyStateTimeout = Duration.ofMinutes(3) waitForTcpPorts = false removeOrphans = true // this is to avoid recreating the containers // specially l1-node-genesis-generator which corrupts the state if run more than once // without cleaning the volumes noRecreate = true projectName = "docker" } localStackPostgresDbOnly { startedServices = ["postgres"] useComposeFiles = [ "${project.rootDir.path}/docker/compose-tracing-v2.yml" ] waitForHealthyStateTimeout = Duration.ofMinutes(3) waitForTcpPorts = true removeOrphans = true noRecreate = true projectName = "docker" } localStackForStateRecovery { startedServices = [ "postgres", "sequencer", "l1-node-genesis-generator", "l1-el-node", "l1-cl-node", "blobscan-api", "blobscan-indexer", "redis", ] composeAdditionalArgs = [ "--profile", "l1", "--profile", "l2", "--profile", "staterecovery" ] useComposeFiles = [ "${project.rootDir.path}/docker/compose-tracing-v2-staterecovery-extension.yml" ] waitForHealthyStateTimeout = Duration.ofMinutes(3) waitForTcpPorts = false removeOrphans = true // this is to avoid recreating the containers // specially l1-node-genesis-generator which corrupts the state if run more than once // without cleaning the volumes noRecreate = true projectName = "docker" } } static Boolean hasKotlinPlugin(Project proj) { return proj.plugins.hasPlugin("org.jetbrains.kotlin.jvm") } static Boolean hasJavaPlugin(Project proj) { return (proj.plugins.hasPlugin("java") || proj.plugins.hasPlugin("java-library")) } static Boolean hasJavaOrKotlinPlugins(Project proj) { return (hasKotlinPlugin(proj) || hasJavaPlugin(proj)) }