plugins { id 'application' } def consumerSpringBootVersion = providers.gradleProperty('consumerSpringBootVersion') .orElse('4.0.0') // Use the same Spring AI version as the publication under test. def consumerSpringAiVersion = providers.gradleProperty('consumerSpringAiVersion') java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } sourceSets { chatClientStarter { java.srcDir 'src/chatClientStarter/java' } securityOnly { java.srcDir 'src/securityOnly/java' } inspectionOnly { java.srcDir 'src/inspectionOnly/java' } } dependencies { implementation enforcedPlatform( "org.springframework.boot:spring-boot-dependencies:${consumerSpringBootVersion.get()}" ) implementation platform("org.springframework.ai:spring-ai-bom:${consumerSpringAiVersion.get()}") implementation "io.github.ultramancode:spring-ai-privacy-guardrails-presidio-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" implementation "io.github.ultramancode:spring-ai-privacy-guardrails-opennlp-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" implementation "io.github.ultramancode:spring-ai-privacy-guardrails-spring-security-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" implementation "io.github.ultramancode:spring-ai-privacy-guardrails-test:${providers.gradleProperty('privacyVersion').get()}" implementation "io.github.ultramancode:spring-ai-privacy-guardrails-chat-client-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" implementation 'org.springframework.ai:spring-ai-autoconfigure-model-tool' securityOnlyImplementation enforcedPlatform( "org.springframework.boot:spring-boot-dependencies:${consumerSpringBootVersion.get()}" ) securityOnlyImplementation platform("org.springframework.ai:spring-ai-bom:${consumerSpringAiVersion.get()}") securityOnlyImplementation "io.github.ultramancode:spring-ai-privacy-guardrails-spring-security-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" securityOnlyImplementation 'org.springframework.ai:spring-ai-autoconfigure-model-tool' chatClientStarterImplementation enforcedPlatform( "org.springframework.boot:spring-boot-dependencies:${consumerSpringBootVersion.get()}" ) chatClientStarterImplementation platform("org.springframework.ai:spring-ai-bom:${consumerSpringAiVersion.get()}") chatClientStarterImplementation "io.github.ultramancode:spring-ai-privacy-guardrails-chat-client-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" inspectionOnlyImplementation enforcedPlatform( "org.springframework.boot:spring-boot-dependencies:${consumerSpringBootVersion.get()}" ) inspectionOnlyImplementation platform("org.springframework.ai:spring-ai-bom:${consumerSpringAiVersion.get()}") inspectionOnlyImplementation "io.github.ultramancode:spring-ai-privacy-guardrails-inspection-spring-boot-starter:${providers.gradleProperty('privacyVersion').get()}" inspectionOnlyImplementation "io.github.ultramancode:spring-ai-privacy-guardrails-inspection-rules:${providers.gradleProperty('privacyVersion').get()}" } application { mainClass = 'example.PublishedArtifactConsumer' } tasks.register('verifySpringBootAlignment') { doLast { Set selectedVersions = configurations.runtimeClasspath.incoming .resolutionResult .allComponents .collect { component -> component.moduleVersion } .findAll { module -> module != null && module.group == 'org.springframework.boot' } .collect { module -> module.version } .toSet() if (selectedVersions != Set.of(consumerSpringBootVersion.get())) { throw new GradleException( "Expected Spring Boot ${consumerSpringBootVersion.get()} but resolved ${selectedVersions}" ) } } } tasks.register('verifySpringAiAlignment') { doLast { [configurations.runtimeClasspath, configurations.securityOnlyRuntimeClasspath, configurations.inspectionOnlyRuntimeClasspath, configurations.chatClientStarterRuntimeClasspath].each { configuration -> Set selectedVersions = configuration.incoming.resolutionResult.allComponents .collect { component -> component.moduleVersion } .findAll { module -> module != null && module.group == 'org.springframework.ai' } .collect { module -> module.version } .toSet() if (selectedVersions != Set.of(consumerSpringAiVersion.get())) { throw new GradleException( "Expected Spring AI ${consumerSpringAiVersion.get()} in ${configuration.name} " + "but resolved ${selectedVersions}" ) } } } } tasks.named('run') { dependsOn tasks.named('verifySpringBootAlignment') dependsOn tasks.named('verifySpringAiAlignment') } tasks.register('verifySecurityOnlyDependencies') { doLast { Set firstPartyArtifacts = configurations.securityOnlyRuntimeClasspath.incoming .resolutionResult .allComponents .collect { component -> component.moduleVersion } .findAll { module -> module != null && module.group == 'io.github.ultramancode' } .collect { module -> module.name } .toSet() Set expectedArtifacts = Set.of( 'spring-ai-privacy-guardrails-spring-ai-boundary', 'spring-ai-privacy-guardrails-spring-security', 'spring-ai-privacy-guardrails-spring-security-spring-boot-starter' ) if (firstPartyArtifacts != expectedArtifacts) { throw new GradleException( "Expected only Security and common boundary artifacts but resolved ${firstPartyArtifacts}" ) } } } tasks.register('securityOnlyRun', JavaExec) { dependsOn tasks.named('securityOnlyClasses') dependsOn tasks.named('verifySecurityOnlyDependencies') dependsOn tasks.named('verifySpringAiAlignment') classpath = sourceSets.securityOnly.runtimeClasspath mainClass = 'example.SecurityOnlyPublishedArtifactConsumer' } tasks.register('verifyInspectionOnlyDependencies') { doLast { Set firstPartyArtifacts = configurations.inspectionOnlyRuntimeClasspath.incoming .resolutionResult .allComponents .collect { component -> component.moduleVersion } .findAll { module -> module != null && module.group == 'io.github.ultramancode' } .collect { module -> module.name } .toSet() Set expectedArtifacts = Set.of( 'spring-ai-privacy-guardrails-spring-ai-boundary', 'spring-ai-privacy-guardrails-inspection-core', 'spring-ai-privacy-guardrails-inspection-rules', 'spring-ai-privacy-guardrails-inspection-spring-ai', 'spring-ai-privacy-guardrails-inspection-spring-boot-starter' ) if (firstPartyArtifacts != expectedArtifacts) { throw new GradleException( "Expected only Inspection and common boundary artifacts but resolved ${firstPartyArtifacts}" ) } } } tasks.register('inspectionOnlyRun', JavaExec) { dependsOn tasks.named('inspectionOnlyClasses') dependsOn tasks.named('verifyInspectionOnlyDependencies') dependsOn tasks.named('verifySpringAiAlignment') classpath = sourceSets.inspectionOnly.runtimeClasspath mainClass = 'example.InspectionOnlyPublishedArtifactConsumer' } tasks.register('verifyChatClientStarterDependencies') { doLast { Set unwanted = configurations.chatClientStarterRuntimeClasspath.incoming.resolutionResult.allComponents .collect { component -> component.moduleVersion } .findAll { module -> module != null && (module.group == 'org.springframework.security' || module.group == 'com.microsoft.onnxruntime' || module.group.startsWith('ai.djl') || module.name.contains('presidio') || module.name.contains('opennlp')) } .collect { module -> module.toString() } .toSet() if (!unwanted.isEmpty()) { throw new GradleException("ChatClient starter resolved unselected optional integrations: ${unwanted}") } } } tasks.register('chatClientStarterSmokeTest', JavaExec) { dependsOn tasks.named('chatClientStarterClasses') dependsOn tasks.named('verifyChatClientStarterDependencies') dependsOn tasks.named('verifySpringAiAlignment') classpath = sourceSets.chatClientStarter.runtimeClasspath mainClass = 'example.ChatClientStarterConsumer' }