### Quick Start - Mac OS / Linux Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/2-getting-started.md Commands to create a new project, configure the build.gradle file, and generate a quick start project with a webflux entry point. ```bash mkdir scaffold-quick-start cd scaffold-quick-start echo "plugins { id 'co.com.bancolombia.cleanArchitecture' version '3.28.0' }" > build.gradle gradle wrapper ./gradlew ca --name=ScaffoldQuickStart ./gradlew gep --type webflux ./gradlew bootRun ``` -------------------------------- ### Quick Start - Windows (CMD) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/2-getting-started.md CMD commands to create a new project, configure the build.gradle file, and generate a quick start project with a webflux entry point. ```cmd @echo off :: Create a directory and navigate into it mkdir scaffold-quick-start cd scaffold-quick-start :: Create the build.gradle file with the specified content ( echo plugins { echo id 'co.com.bancolombia.cleanArchitecture' version '3.28.0' echo } ) > build.gradle :: Run the Gradle commands gradle wrapper gradlew ca --name=ScaffoldQuickStart gradlew gep --type webflux gradlew bootRun ``` -------------------------------- ### Quick Start - Windows (PowerShell) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/2-getting-started.md PowerShell commands to create a new project, configure the build.gradle file, and generate a quick start project with a webflux entry point. ```powershell # Create a directory and navigate into it New-Item -ItemType Directory -Name "scaffold-quick-start" Set-Location -Path "scaffold-quick-start" # Create the build.gradle file with the specified content @" plugins { id 'co.com.bancolombia.cleanArchitecture' version '3.28.0' }"@ | Set-Content -Path "build.gradle" # Run the Gradle commands gradle wrapper .\gradlew ca --name=ScaffoldQuickStart .\gradlew gep --type webflux .\gradlew bootRun ``` -------------------------------- ### List Available Tasks Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/2-getting-started.md Command to list all available tasks provided by the Gradle plugin. ```bash gradle tasks ``` -------------------------------- ### MCP Entry Point Usage Examples Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Examples demonstrating various configurations for generating an MCP entry point. ```shell # Generate with all capabilities enabled (default: includes security and audit) gradle generateEntryPoint --type=mcp # Only Tools grade generateEntryPoint --type=mcp --enable-tools=true --enable-resources=false --enable-prompts=false # Only Resources grade generateEntryPoint --type=mcp --enable-tools=false --enable-resources=true --enable-prompts=false # With custom name grade generateEntryPoint --type=mcp --name=BancolombiaAssistant # Without security (development mode only) grade generateEntryPoint --type=mcp --enable-security=false # Without audit logging grade generateEntryPoint --type=mcp --enable-audit=false ``` -------------------------------- ### Local Development Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/README.md Starts a local development server for live previewing changes. ```bash $ yarn start ``` -------------------------------- ### Installation Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/README.md Installs project dependencies using Yarn. ```bash $ yarn ``` -------------------------------- ### Kafka Strimzi Consumer Usage Example Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Examples of generating an entry point for consuming Kafka messages using Strimzi. ```shell gradle generateEntryPoint --type=kafkastrimzi gradle gep --type=kafkastrimzi ``` ```shell gradle generateEntryPoint --type=kafkastrimzi --name=myConsumer --topic-consumer=myTopic grade gep --type=kafkastrimzi --name=myConsumer --topic-consumer=myTopic ``` -------------------------------- ### Project Build Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/blockhound/before-err.txt This snippet shows the Gradle build configuration for a Java project, including repositories, plugins, Java version, dependencies, and Jacoco reporting setup. ```gradle allprojects { repositories { mavenCentral() maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/milestone" } } } subprojects { apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure sourceCompatibility = JavaVersion.VERSION_17 test { useJUnitPlatform() } dependencies { implementation 'io.projectreactor:reactor-core' implementation 'io.projectreactor.addons:reactor-extra' compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } test.finalizedBy(project.tasks.jacocoTestReport) jacocoTestReport { dependsOn test reports { xml.setRequired true xml.setOutputLocation file("${buildDir}/reports/jacoco.xml") csv.setRequired false html.setOutputLocation file("${buildDir}/reports/jacocoHtml") } } } jacoco { toolVersion = "${jacocoVersion}" reportsDirectory = file("$buildDir/reports") } tasks.register('jacocoMergedReport', JacocoReport) { dependsOn = subprojects.jacocoTestReport additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.setFrom files(subprojects.sourceSets.main.output) executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec') reports { xml.setRequired true csv.setRequired false html.setRequired true } } tasks.withType(JavaCompile).configureEach { options.compilerArgs = [ '-Amapstruct.suppressGeneratorTimestamp=true' ] } tasks.named('wrapper') { gradleVersion = '7.6.1' } ``` -------------------------------- ### Create a Prompt Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Example Java code for creating a Prompt component using annotations like @Component, @McpPrompt, and @McpArg. ```java @Component public class SupportPrompt { @McpPrompt( name = "customer-support", description = "Generates a customer support prompt") public Mono customerSupport( @McpArg(name = "issue", required = true) String issue) { return Mono.fromCallable(() -> { // Implementation }); } } ``` -------------------------------- ### Create a Resource Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Example Java code for creating a Resource component using annotations like @Component, @McpResource, and @McpResourceParam. ```java @Component public class ConfigResource { @McpResource( uri = "resource://config/app", name = "app-config", description = "Application configuration") public Mono getConfig() { return Mono.fromCallable(() -> { // Implementation }); } } ``` -------------------------------- ### Create a Tool Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Example Java code for creating a Tool component using annotations like @Component, @McpTool, and @McpToolParam. ```java @Component public class CalculatorTool { @McpTool(name = "multiply", description = "Multiplies two numbers") public Mono multiply( @McpToolParam(description = "First number", required = true) int a, @McpToolParam(description = "Second number", required = true) int b) { return Mono.just(a * b); } } ``` -------------------------------- ### Wrapper Gradle Version Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.4-layout-build-directory/main-before.txt Sets the Gradle version for the wrapper task. ```gradle tasks.named('wrapper') { gradleVersion = '8.2.1' } ``` -------------------------------- ### Usage Examples Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Various Gradle commands demonstrating different configurations for generating an agent entry point, including options for Kafka, MCP client, and name. ```shell # Full agent: REST + Kafka + MCP client (Default behavior) gradle generateEntryPoint --type=agent --name=my-agent # Minimal REST-only agent without async transport and without MCP # Generates spring-ai-adapter as the ChatGateway implementation grade generateEntryPoint --type=agent --name=my-agent --agent-enable-kafka=false --agent-enable-mcp-client=false # Agent with Kafka only # Generates spring-ai-adapter and Kafka modules grade generateEntryPoint --type=agent --name=my-agent --agent-enable-mcp-client=false # Agent with MCP client only (REST + MCP) grade generateEntryPoint --type=agent --name=my-agent --agent-enable-kafka=false ``` -------------------------------- ### Gradle Plugin Declaration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/2-getting-started.md This snippet shows how to declare the cleanArchitecture plugin in your build.gradle file. ```groovy plugins { id 'co.com.bancolombia.cleanArchitecture' version '3.28.0' } ``` -------------------------------- ### Installing Git pre-commit hooks Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Command to install the project's pre-commit hook for code formatting and testing. ```bash ./gradlew installGitHooks ``` -------------------------------- ### Generate Entry Point Command Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Examples of how to use the 'generateEntryPoint' task with Gradle, including its alias 'gep'. ```shell gradle generateEntryPoint --type=[entryPointType] gradle gep --type [entryPointType] ``` -------------------------------- ### Generating a new project using settings.gradle Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Example `build.gradle` and `settings.gradle` content for generating a new project with a locally published plugin version. ```groovy plugins { id "co.com.bancolombia.cleanArchitecture" version "2.4.1.1" } ``` ```groovy pluginManagement { repositories { mavenLocal() gradlePluginPortal() } } ``` -------------------------------- ### Example audit log output Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Demonstrates the format and content of audit log entries generated when audit logging is enabled. ```text πŸ“Š [AUDIT] TOOL llamado por: a1b2c3d4-client-id | MΓ©todo: ExampleTool.echo | Args: ["hello"] βœ… [AUDIT] TOOL exitoso | Client: a1b2c3d4-client-id | MΓ©todo: ExampleTool.echo | Tiempo: 45ms ``` -------------------------------- ### Generating a new project using build.gradle Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Example `build.gradle` content for generating a new project with a locally published plugin version. ```groovy buildscript { repositories { mavenLocal() mavenCentral() } dependencies { classpath "co.com.bancolombia.cleanArchitecture:scaffold-clean-architecture:2.4.1.1" } } apply plugin: "co.com.bancolombia.cleanArchitecture" ``` -------------------------------- ### Whitelisting Dependencies Example Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/10-validate-structure.md Example of how to whitelist dependencies in the build.gradle file to avoid validation failures. ```groovy // build.gradle cleanPlugin { modelProps { whitelistedDependencies = "my-bom, , " } } ``` -------------------------------- ### Project Build Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/blockhound/after.txt This snippet shows the Gradle build configuration for a Java project, including repository definitions, plugin applications, Java version, test configuration, and dependency management. ```gradle allprojects { repositories { mavenCentral() maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/milestone" } } } subprojects { apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure sourceCompatibility = JavaVersion.VERSION_17 test { useJUnitPlatform() } dependencies { implementation 'io.projectreactor:reactor-core' implementation 'io.projectreactor.addons:reactor-extra' testImplementation 'io.projectreactor.tools:blockhound-junit-platform:{{BLOCK_HOUND_VERSION}}' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } tasks.withType(Test).configureEach { if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { jvmArgs += [ "-XX:+AllowRedefinitionToAddDeleteMethods" ] } } test.finalizedBy(project.tasks.jacocoTestReport) jacocoTestReport { dependsOn test reports { xml.setRequired true xml.setOutputLocation file("${buildDir}/reports/jacoco.xml") csv.setRequired false html.setOutputLocation file("${buildDir}/reports/jacocoHtml") } } } jacoco { toolVersion = "${jacocoVersion}" reportsDirectory = file("$buildDir/reports") } tasks.register('jacocoMergedReport', JacocoReport) { dependsOn = subprojects.jacocoTestReport additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.setFrom files(subprojects.sourceSets.main.output) executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec') reports { xml.setRequired true csv.setRequired false html.setRequired true } } tasks.withType(JavaCompile).configureEach { options.compilerArgs = [ '-Amapstruct.suppressGeneratorTimestamp=true' ] } tasks.named('wrapper') { gradleVersion = '7.6.1' } ``` -------------------------------- ### Jacoco Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.4-layout-build-directory/main-before.txt Configures the Jacoco tool version and reports directory. ```gradle jacoco { toolVersion = "${jacocoVersion}" reportsDirectory.set(file("$buildDir/reports")) } ``` -------------------------------- ### Generated Entry Point Structure Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Example file structure generated for the entry point, showing the organization within the infrastructure directory. ```bash πŸ“¦infrastructure ┣ πŸ“‚entry-points ┃ β”— πŸ“‚generic ┃ ┃ ┣ πŸ“‚src ┃ ┃ ┃ ┣ πŸ“‚main ┃ ┃ ┃ ┃ β”— πŸ“‚java ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚[package] ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚generic ┃ ┃ ┃ β”— πŸ“‚test ┃ ┃ ┃ ┃ β”— πŸ“‚java ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚[package] ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚generic ┃ ┃ β”— πŸ“œbuild.gradle ``` -------------------------------- ### Subproject Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.4-layout-build-directory/main-before.txt Applies common plugins, sets source compatibility, configures testing, and defines dependencies for subprojects. ```gradle subprojects { apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure sourceCompatibility = JavaVersion.VERSION_17 test { useJUnitPlatform() } dependencies { implementation 'io.projectreactor:reactor-core' implementation 'io.projectreactor.addons:reactor-extra' testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.8.RELEASE' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } tasks.withType(Test).configureEach { if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { jvmArgs += [ "-XX:+AllowRedefinitionToAddDeleteMethods" ] } } test.finalizedBy(project.tasks.jacocoTestReport) jacocoTestReport { dependsOn test reports { xml.setRequired true xml.setOutputLocation file("${buildDir}/reports/jacoco.xml") csv.setRequired false html.setOutputLocation file("${buildDir}/reports/jacocoHtml") } } } ``` -------------------------------- ### Setting custom plugin version Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Example of how to change the plugin version in the `gradle.properties` file for local testing. ```properties systemProp.version=2.4.1.1 ``` -------------------------------- ### Subproject Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.4-layout-build-directory/main-after.txt Applies common plugins, sets Java compatibility, configures testing, and defines dependencies for subprojects. ```gradle subprojects { apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure sourceCompatibility = JavaVersion.VERSION_17 test { useJUnitPlatform() } dependencies { implementation 'io.projectreactor:reactor-core' implementation 'io.projectreactor.addons:reactor-extra' testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.8.RELEASE' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } tasks.withType(Test).configureEach { if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { jvmArgs += [ "-XX:+AllowRedefinitionToAddDeleteMethods" ] } } test.finalizedBy(project.tasks.jacocoTestReport) jacocoTestReport { dependsOn test reports { xml.setRequired true xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml") csv.setRequired false html.setOutputLocation layout.buildDirectory.dir("reports/jacocoHtml") } } } ``` -------------------------------- ### Gradle Settings Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.14-gradle-cache/settings-after.txt This snippet shows the configuration of repositories, build cache, and project inclusions in a Gradle settings file. ```gradle pluginManagement { repositories { //mavenLocal() //maven { url = '...' } maven { url = "https://repo.spring.io/snapshot" } gradlePluginPortal() } } buildCache { local { directory = new File(rootDir, 'build-cache') } } rootProject.name = 'ms_test' include ':app-service' include ':model' include ':usecase' project(':app-service').projectDir = file('./applications/app-service') project(':model').projectDir = file('./domain/model') project(':usecase').projectDir = file('./domain/usecase') include ':r2dbc-postgresql' project(':r2dbc-postgresql').projectDir = file('./infrastructure/driven-adapters/r2dbc-postgresql') include ':reactive-web' project(':reactive-web').projectDir = file('./infrastructure/entry-points/reactive-web') ``` -------------------------------- ### Generated Driven Adapter Structure Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/4-generate-driven-adapter.md Example file structure of a generated JPA repository driven adapter. ```bash πŸ“¦infrastructure ┣ πŸ“‚driven-adapters ┃ β”— πŸ“‚jpa-repository ┃ ┃ ┣ πŸ“‚src ┃ ┃ ┃ ┣ πŸ“‚main ┃ ┃ ┃ ┃ β”— πŸ“‚java ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚[package] ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚jpa ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ πŸ“‚config ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“œDBSecret.java ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ πŸ“‚helper ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“œAdapterOperations.java ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣ πŸ“œJPARepository.java ┃ ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“œJPARepositoryAdapter.java ┃ ┃ ┃ β”— πŸ“‚test ┃ ┃ ┃ ┃ β”— πŸ“‚java ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚[package] ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚jpa ┃ ┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚helper ┃ ┃ β”— πŸ“œbuild.gradle ``` -------------------------------- ### Main Build Script Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-9-java-toolchain/main-before.txt This snippet shows the main configuration for a Gradle build, including plugin application, repository definitions, and subproject configurations. ```gradle apply plugin: 'info.solidsoft.pitest.aggregator' allprojects { repositories { mavenCentral() maven { url = "https://repo.spring.io/snapshot" } maven { url = "https://repo.spring.io/milestone" } } } subprojects { apply plugin: 'info.solidsoft.pitest' apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } test { useJUnitPlatform() } dependencies { implementation platform('software.amazon.awssdk:bom:2.29.15') implementation 'io.projectreactor:reactor-core' implementation 'io.projectreactor.addons:reactor-extra' testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.10.RELEASE' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } tasks.withType(Test).configureEach { if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { jvmArgs += [ "-XX:+AllowRedefinitionToAddDeleteMethods" ] } } test.finalizedBy(project.tasks.jacocoTestReport) pitest { targetClasses = ['co.com.bancolombia.*'] excludedClasses = [] excludedTestClasses = [] pitestVersion = '1.22.0' verbose = false outputFormats = ['XML', 'HTML'] threads = 8 exportLineCoverage = true useClasspathFile = true timestampedReports = false //mutators = ['STRONGER', 'DEFAULTS'] fileExtensionsToFilter.addAll('xml', 'orbit') junit5PluginVersion = '1.2.3' failWhenNoMutations = false jvmArgs = ["-XX:+AllowRedefinitionToAddDeleteMethods"] } jacocoTestReport { dependsOn test, 'pitest' reports { xml.setRequired true xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml") csv.setRequired false html.setOutputLocation layout.buildDirectory.dir("reports/jacocoHtml") } } } jacoco { toolVersion = "${jacocoVersion}" reportsDirectory.set(layout.buildDirectory.dir("reports")) } tasks.register('jacocoMergedReport', JacocoReport) { dependsOn = [test, subprojects.jacocoTestReport, pitestReportAggregate] additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.setFrom files(subprojects.sourceSets.main.output) executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec') reports { xml.setRequired true csv.setRequired false html.setRequired true } } tasks.withType(JavaCompile).configureEach { options.compilerArgs = [ '-Amapstruct.suppressGeneratorTimestamp=true' ] } pitestReportAggregate { doLast { def reportDir = layout.buildDirectory.dir("reports/pitest").get().asFile def consolidatedReport = new File(reportDir, 'mutations.xml') consolidatedReport.withWriter { writer -> writer.write("\n") subprojects.each { subproject -> def xmlReport = subproject.layout.buildDirectory.file("reports/pitest/mutations.xml").get().asFile if (xmlReport.exists()) { def xmlContent = xmlReport.text xmlContent = xmlContent.replaceAll("<\\?xml[^>]*>", "") xmlContent = xmlContent.replaceAll("", "") writer.write(xmlContent.trim() + "\n") } } writer.write("") } } } tasks.named('wrapper') { gradleVersion = '9.2.1' } ``` -------------------------------- ### Gradle Build Script Snippet Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/junit-platform/without.txt Example of Gradle build script configuration, including task dependencies and source compatibility. ```gradle compileJava.dependsOn validateStructure sourceCompatibility = JavaVersion.VERSION_11 dependencies { ``` -------------------------------- ### Project Build Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-9-java-toolchain/main-after.txt This snippet shows the main Gradle build script configuration, including plugins, repositories, Java toolchain settings, dependencies, and task configurations for testing and code coverage. ```gradle apply plugin: 'info.solidsoft.pitest.aggregator' allprojects { repositories { mavenCentral() maven { url = "https://repo.spring.io/snapshot" } maven { url = "https://repo.spring.io/milestone" } } } subprojects { apply plugin: 'info.solidsoft.pitest' apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } test { useJUnitPlatform() } dependencies { implementation platform('software.amazon.awssdk:bom:2.29.15') implementation 'io.projectreactor:reactor-core' implementation 'io.projectreactor.addons:reactor-extra' testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.10.RELEASE' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' compileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } tasks.withType(Test).configureEach { if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { jvmArgs += [ "-XX:+AllowRedefinitionToAddDeleteMethods" ] } } test.finalizedBy(project.tasks.jacocoTestReport) pitest { targetClasses = ['co.com.bancolombia.*'] excludedClasses = [] excludedTestClasses = [] pitestVersion = '1.22.0' verbose = false outputFormats = ['XML', 'HTML'] threads = 8 exportLineCoverage = true useClasspathFile = true withHistory = true timestampedReports = false //mutators = ['STRONGER', 'DEFAULTS'] fileExtensionsToFilter.addAll('xml', 'orbit') junit5PluginVersion = '1.2.3' failWhenNoMutations = false jvmArgs = ["-XX:+AllowRedefinitionToAddDeleteMethods"] } jacocoTestReport { dependsOn test, 'pitest' reports { xml.setRequired true xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml") csv.setRequired false html.setOutputLocation layout.buildDirectory.dir("reports/jacocoHtml") } } } jacoco { toolVersion = "${jacocoVersion}" reportsDirectory.set(layout.buildDirectory.dir("reports")) } tasks.register('jacocoMergedReport', JacocoReport) { dependsOn = [test, subprojects.jacocoTestReport, pitestReportAggregate] additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.setFrom files(subprojects.sourceSets.main.output) executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec') reports { xml.setRequired true csv.setRequired false html.setRequired true } } tasks.withType(JavaCompile).configureEach { options.compilerArgs = [ '-Amapstruct.suppressGeneratorTimestamp=true' ] } pitestReportAggregate { doLast { def reportDir = layout.buildDirectory.dir("reports/pitest").get().asFile def consolidatedReport = new File(reportDir, 'mutations.xml') consolidatedReport.withWriter { writer -> writer.write("\n") subprojects.each { subproject -> def xmlReport = subproject.layout.buildDirectory.file("reports/pitest/mutations.xml").get().asFile if (xmlReport.exists()) { def xmlContent = xmlReport.text xmlContent = xmlContent.replaceAll("<\\?xml[^>]*>", "") xmlContent = xmlContent.replaceAll("", "") writer.write(xmlContent.trim() + "\n") } } writer.write("") } } } tasks.named('wrapper') { gradleVersion = '9.2.1' } ``` -------------------------------- ### Gradle Build Script Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/sonar-rules/before.txt This snippet shows the configuration for SonarQube within a Gradle build script, including properties for encoding, modules, sources, exclusions, test paths, and coverage. ```gradle buildscript { ext { cleanArchitectureVersion = '3.6.1' springBootVersion = '3.1.1' sonarVersion = '4.2.1.3168' jacocoVersion = '0.8.10' lombokVersion = '1.18.28' } } plugins { id 'co.com.bancolombia.cleanArchitecture' version "${cleanArchitectureVersion}" id 'org.springframework.boot' version "${springBootVersion}" apply false id 'org.sonarqube' version "${sonarVersion}" id 'jacoco' } apply plugin: 'co.com.bancolombia.cleanArchitecture' sonarqube { def modules = subprojects.projectDir.collect { "${it.toString().replace(project.projectDir.toString() + "/", "")}" } properties { property "sonar.sourceEnconding", "UTF-8" property "sonar.modules", "${modules.join(',')}" property "sonar.sources", "src,deployment,settings.gradle,main.gradle,build.gradle,${modules.collect { "${it}/build.gradle" }.join(',')}" property "sonar.exclusions","**/MainApplication.java" property "sonar.test", "src/test" property "sonar.java.binaries", "" property "sonar.junit.reportsPath", "" property "sonar.java.coveragePlugin", "jacoco" property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml" } } apply from: './main.gradle' ``` -------------------------------- ### Gradle Build Script Example Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.4-layout-build-directory/app-service-after.txt This snippet shows a typical Gradle build script configuration for a Spring Boot application, including dependencies and custom tasks. ```gradle apply plugin: 'org.springframework.boot' dependencies { implementation project(':model') implementation project(':usecase') implementation 'org.springframework.boot:spring-boot-starter' runtimeOnly('org.springframework.boot:spring-boot-devtools') testImplementation 'com.tngtech.archunit:archunit:1.1.0' testImplementation 'com.fasterxml.jackson.core:jackson-databind' } tasks.register('explodedJar', Copy) { with jar into layout.buildDirectory.dir("exploded") } jar { // To disable the *-plain.jar enabled = false } bootJar { // Sets output jar name archiveFileName = "${project.getParent().getName()}.${archiveExtension.get()}" } ``` -------------------------------- ### appendToProperties Method Example Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Gets or creates an ObjectNode for application.yaml to add custom properties. ```java builder .appendToProperties("spring.datasource") .put("url","jdbc:h2:mem:test") .put("driverClassName","org.h2.Driver"); ``` -------------------------------- ### ApiRest Controller Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/rest/mapping-after.txt A Spring Boot RestController demonstrating POST, GET, PUT, PATCH, and DELETE mappings. ```java package co.com.bancolombia.api; import lombok.AllArgsConstructor; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE) @AllArgsConstructor public class ApiRest { @PostMapping("/path/a") public String operationA() { return "Hello World"; } @GetMapping(path = "/path/a") public String operationAWithPath() { return "Hello World"; } @GetMapping(value = "/path/b") public String operationBWithValue() { return "Hello World"; } @PutMapping("/path/a/ok") public String operationAWithPathOk() { return "Hello World"; } @PatchMapping(path = "/path/a/ok") public String operationAWithValueOk() { return "Hello World"; } @DeleteMapping(value = "/path/b/ok") public String operationBWithValueOk() { return "Hello World"; } } ``` -------------------------------- ### setupFromTemplate Method Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Loads template definition from a JSON file to set up project structure. ```java public void setupFromTemplate(String resourceGroup) throws IOException, ParamNotFoundException {} ``` -------------------------------- ### Conventional Commits Examples Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Examples of commit messages following the conventional commits specification. ```text test: add functional test for non-standard base libraries ci: support for Ubuntu 18 & CentOS 7 deps: upgrade express to 4.17.1 deps: standardjs as style guide, linter, and formatter ``` -------------------------------- ### Wrapper Task Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest-report-aggregate/main-before.txt Sets the Gradle version for the wrapper task. ```gradle tasks.named('wrapper') { gradleVersion = '9.4.0' } ``` -------------------------------- ### Cloning and setting up local repository Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Steps to fork the project, clone it locally, add the upstream remote, and fetch changes. ```bash git clone git@github.com:username/scaffold-clean-architecture.git cd scaffold-clean-architecture git remote add upstream https://github.com/bancolombia/scaffold-clean-architecture.git git fetch upstream ``` -------------------------------- ### apply main gradle Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest/build-after.txt Applies the main Gradle build script. ```groovy apply from: './main.gradle' ``` -------------------------------- ### appendDependencyToModule Method Example Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/3-contributing.md Adds a new dependency for a specified module, using Utils.buildImplementationFromProject. ```java String dependency = Utils.buildImplementationFromProject(builder.isKotlin(), ":dynamodb"); builder.appendDependencyToModule(APP_SERVICE, dependency); ``` -------------------------------- ### Build Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/README.md Generates static content for deployment. ```bash $ yarn build ``` -------------------------------- ### plugins Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest/build-after.txt Applies various Gradle plugins. ```groovy plugins { id 'info.solidsoft.pitest' version "${pitestVersion}" apply false id 'co.com.bancolombia.cleanArchitecture' version "${cleanArchitectureVersion}" id 'org.springframework.boot' version "${springBootVersion}" apply false id 'org.sonarqube' version "${sonarVersion}" id 'jacoco' } ``` -------------------------------- ### Root Project PITest Aggregator Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest-report-aggregate/main-after.txt Applies the PITest aggregator plugin to the root project. ```gradle apply plugin: 'info.solidsoft.pitest.aggregator' ``` -------------------------------- ### Jacoco Merged Report Task Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/gradle-8.4-layout-build-directory/main-before.txt Defines a task to generate a merged Jacoco report from all subprojects. ```gradle tasks.register('jacocoMergedReport', JacocoReport) { dependsOn = [test, subprojects.jacocoTestReport] additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.setFrom files(subprojects.sourceSets.main.output) executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec') reports { xml.setRequired true csv.setRequired false html.setRequired true } } ``` -------------------------------- ### Project Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest-report-aggregate/main-before.txt Applies the pitest aggregator plugin and configures repositories for all projects. ```gradle apply plugin: 'info.solidsoft.pitest.aggregator' allprojects { repositories { mavenCentral() } } ``` -------------------------------- ### Non-Compliant UseCase Attributes (Concurrency) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/advanced/1-arch-unit-analysis.md Example of a UseCase with non-final attributes ('notifier', 'user'), which can lead to concurrency issues. ```java package co.com.bancolombia.usecase.notifyusers; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class NotifyUsersUseCase { private NotificationGateway notifier; // No Compliant private User user; // No Compliant public void notify(User user) { this.user = user; // some other business logic this.sendMessage() } private void sendMessage() { // send message througth class instance of user notifier.send("notification", user.getEmail()) } } ``` -------------------------------- ### plugins block Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest/build-before.txt Applies various Gradle plugins. ```groovy plugins { id 'co.com.bancolombia.cleanArchitecture' version "${cleanArchitectureVersion}" id 'org.springframework.boot' version "${springBootVersion}" apply false id 'org.sonarqube' version "${sonarVersion}" id 'jacoco' } ``` -------------------------------- ### Basic Command Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/5-generate-entry-point.md Basic Gradle commands to generate an entry point of type 'agent'. ```shell gradle generateEntryPoint --type=agent grade gep --type=agent ``` -------------------------------- ### Generate Helper Command Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/tasks/6-generate-helper.md Examples of how to use the 'generateHelper' or 'gh' Gradle task with the required 'name' parameter. ```shell gradle generateHelper --name=[helperName] ``` ```shell gradle gh --name=[helperName] ``` -------------------------------- ### Compliant UseCase Attributes (Concurrency) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/advanced/1-arch-unit-analysis.md Example of a UseCase with final attributes ('notifier'), promoting immutability and avoiding concurrency issues. ```java package co.com.bancolombia.usecase.notifyusers; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class NotifyUsersUseCase { private final NotificationGateway notifier; // Compliant public void notify(User user) { // some other business logic this.sendMessage(user) } private void sendMessage(User user) { // send message througth input instance of user notifier.send("notification", user.getEmail()) } } ``` -------------------------------- ### Compliant Domain Class Naming (Message) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/advanced/1-arch-unit-analysis.md Example of a compliant domain class named 'Message' without technology names. ```java package co.com.bancolombia.model.message; public class Message { private String contentType; private byte[] content; } ``` -------------------------------- ### Non-Compliant Domain Class Naming (RabbitMessage) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/advanced/1-arch-unit-analysis.md Example of a non-compliant domain class named 'RabbitMessage' which includes a technology name. ```java package co.com.bancolombia.model.rabbitmessage; public class RabbitMessage { private String contentType; private byte[] content; } ``` -------------------------------- ### Compliant Domain Class Naming (User) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/advanced/1-arch-unit-analysis.md Example of a compliant domain class named 'User' without technology suffixes. ```java package co.com.bancolombia.model.user; public class User { private String name; private String email; } ``` -------------------------------- ### Non-Compliant Domain Class Naming (UserRequest) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/docs/advanced/1-arch-unit-analysis.md Example of a non-compliant domain class named 'UserRequest' which includes a technology suffix. ```java package co.com.bancolombia.model.userrequest; public class UserRequest { private String name; private String email; } ``` -------------------------------- ### sonar configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest/build-before.txt Configures SonarQube properties for analysis. ```groovy sonar { def modules = subprojects.projectDir.collect { "${it.toString().replace(project.projectDir.toString() + "/", "")}" } properties { property "sonar.sourceEncoding", "UTF-8" property "sonar.modules", "${modules.join(',')}" property "sonar.sources", "src,deployment,settings.gradle,main.gradle,build.gradle,${modules.collect { "${it}/build.gradle" }.join(',')}" property "sonar.test", "src/test" property "sonar.exclusions", "" property "sonar.java.binaries", "build/classes" property "sonar.junit.reportsPath", "build/test-reports" property "sonar.java.coveragePlugin", "jacoco" property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoMergedReport/jacocoMergedReport.xml" property "sonar.externalIssuesReportPaths", "build/issues.json" } } ``` -------------------------------- ### Subproject Configuration Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest-report-aggregate/main-before.txt Configures subprojects with pitest, java, jacoco, and spring dependency management, including Java toolchain, test settings, and dependencies. ```gradle subprojects { apply plugin: 'info.solidsoft.pitest' apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'io.spring.dependency-management' compileJava.dependsOn validateStructure java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } test { useJUnitPlatform() } dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") } test.finalizedBy(project.tasks.jacocoTestReport) pitest { targetClasses = ['your.package.*'] excludedClasses = [] excludedTestClasses = [] pitestVersion = '1.22.1' verbose = false outputFormats = ['XML', 'HTML'] threads = 8 exportLineCoverage = true useClasspathFile = true withHistory = true timestampedReports = false //mutators = ['STRONGER', 'DEFAULTS'] fileExtensionsToFilter.addAll('xml', 'orbit') junit5PluginVersion = '1.2.3' failWhenNoMutations = false jvmArgs = ["-XX:+AllowRedefinitionToAddDeleteMethods"] } jacocoTestReport { dependsOn test, 'pitest' reports { xml.setRequired true xml.setOutputLocation layout.buildDirectory.file("reports/jacoco.xml") csv.setRequired false html.setOutputLocation layout.buildDirectory.dir("reports/jacocoHtml") } } } ``` -------------------------------- ### Deployment (Using SSH) Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/docs/README.md Deploys the website using SSH. ```bash $ USE_SSH=true yarn deploy ``` -------------------------------- ### PITest Report Aggregation Task Source: https://github.com/bancolombia/scaffold-clean-architecture/blob/master/src/test/resources/pitest-report-aggregate/main-after.txt Defines a task to aggregate PITest reports from all subprojects into a single mutations.xml file. ```gradle pitestReportAggregate { def rootReportDir = layout.buildDirectory.dir("reports/pitest") def subprojectReports = subprojects.collect { subproject -> subproject.layout.buildDirectory.file("reports/pitest/mutations.xml") } doLast { def reportDir = rootReportDir.get().asFile def consolidatedReport = new File(reportDir, 'mutations.xml') consolidatedReport.withWriter { writer -> writer.write("\n") subprojectReports.each { reportProvider -> def xmlReport = reportProvider.get().asFile if (xmlReport.exists()) { def xmlContent = xmlReport.text xmlContent = xmlContent.replaceAll("<\\?xml[^>]*>", "") xmlContent = xmlContent.replaceAll("", "") writer.write(xmlContent.trim() + "\n") } } writer.write("") } } } ```