TNG / ArchUnit

A Java architecture test library, to specify and assert architecture rules in plain Java
http://archunit.org
Apache License 2.0
3.18k stars 287 forks source link

Configuring a Custom gradle Plugin to Run on Client Project #1326

Closed vin0010 closed 1 month ago

vin0010 commented 1 month ago

In our organization, we have a repository where we export a variety of plugins related to checkstyle, PMD, component testing, and Liquibase, among other things. I created a simple plugin with a task that invokes a rule check.

After exporting the plugin and applying it to my child project, I can see the task. However, when I run the task, the rules only check the classes within the plugin. They do not scan any classes in the child project. It seems as though the plugin operates as a self-contained unit.

How can I configure my plugin to run on the classpath of the client project?

Plugin

class ArchUnitPlugin : Plugin<Project> {
  override fun apply(project: Project) {
    val runArchUnitTests =
      project.tasks.register("runArchUnitTests", Test::class.java) {
        group = "verification"
        description = "Runs ArchUnit tests"

        val sourceSets = project.extensions.getByType<SourceSetContainer>()
        val main = sourceSets.getByName("main")

        classpath = project.files(main.runtimeClasspath)
        doLast {
          println("Task running!!!!!!!!!!!!!!!")
          ServiceAnnotationVerifier().verifyServiceAnnotations()
        }
      }
    runArchUnitTests.configure { dependsOn("test") }
  }
}

Rule inside plugin project


class ServiceAnnotationVerifier {
fun verifyServiceAnnotations() {
val importedClasses = ClassFileImporter().importPackages("..service..")
val servicesShouldBeAnnotatedWithService =
  ArchRuleDefinition.classes()
    .that()
    .resideInAPackage("..service..")
    .and()
    .haveSimpleNameNotEndingWith("Test")
    .should()
    .beAnnotatedWith(Service::class.java)
    .orShould()
    .beAnnotatedWith(Component::class.java)
    .because("Need to ensure that all service classes are annotated with @Service")

servicesShouldBeAnnotatedWithService.check(importedClasses)

} }


After applying the plugin in child project and when I run `./gradlew :runArchUnitTests` I got 

Task :runArchUnitTests FAILED Task running!!!!!!!!!!!!!!!

FAILURE: Build failed with an exception.

I am new to plugins and need suggestion on whats wrong.

Thank you.

hankem commented 1 month ago

Do you know the ArchUnit Gradle plugin from the Société Générale? It might already cover your use case without having to implement your own plugin.

vin0010 commented 1 month ago

Do you know the ArchUnit Gradle plugin from the Société Générale? It might already cover your use case without having to implement your own plugin.

Let me check, due to an internal regulation, we need to come up with our own plugin.

vin0010 commented 1 month ago

I did check that, it seems like they used a fancy mechanism to execute rules. Is there a simlper way to execute them in client?

Also my question mostly about how this plugin or task has access to child project classes during runtime?

Thank you.