Codex
Codex

Reputation: 1281

Custom gradle Plugin to Run on Client Projects code

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 archunit 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.

* What went wrong:
Execution failed for task ':runArchUnitTests'.
> Rule 'classes that reside in a package '..service..' and have simple name not ending with 'Test' should be annotated with @Service or should be annotated with @Component, because Need to ensure that all service classes are annotated with @Service' failed to check any classes. This means either that no classes have been passed to the rule at all, or that no classes passed to the rule matched the `that()` clause. To allow rules being evaluated without checking any classes you can either use `ArchRule.allowEmptyShould(true)` on a single rule or set the configuration property `archRule.failOnEmptyShould = false` to change the behavior globally.

I am new to plugins and need suggestion on whats wrong. Created an issue here as well

Thank you.

Upvotes: 0

Views: 29

Answers (1)

Manfred
Manfred

Reputation: 3142

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.

Upvotes: 0

Related Questions