Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype plugin stubs generation #209 #232

Closed
wants to merge 20 commits into from
Closed

Conversation

andriy-dmytruk
Copy link
Contributor

@andriy-dmytruk andriy-dmytruk commented Jan 17, 2025

This adds support for generating Maven and Gradle stubs (#209).

Description

A plugin task configuration can be provided in a micronaut repo, like micronaut-json-schema. It is marked and configured using @PluginTask annotation. Then, @GenerateGradlePlugin or @GenerateMavenMojo annotations can be used in plugin repositories to generate plugin sources.

This has the advantage:

  • Plugin parameters can be defined in a single place and do not need to be repeated in plugins (currently we repeat parameters once for Maven and three times for Gradle).
  • This makes sure that parameter names and parameter defaults are consistent between plugins reducing manual errors.
  • The documentation needs to be written only once improving consistency again.

As an example, OpenAPI plugin has more than 40 parameters, which can be added and modified. This would simplify that effort.

Example

Example is provided in the test-suite-plugin-.
A plugin task can be configured with

@PluginTask
public record GenerateSimpleRecordTask(
    @PluginTaskParameter(required = true, globalProperty = "typeName")
    String typeName,
    @PluginTaskParameter(defaultValue = "1", globalProperty = "version")
    Integer version,
    @PluginTaskParameter(defaultValue = "com.example", globalProperty = "packageName")
    String packageName,
    Map<String, String> properties,
    List<String> javadoc,
    @PluginTaskParameter(output = true, directory = true, required = true)
    File outputFolder
) {

    /**
     * Generate a simple record in the supplied package and with the specified version.
     * This javadoc will be copied to the respected plugin implementations.
     */
    @PluginTaskExecutable
    public void generateSimpleRecord() {
       /* ... */
    }
}

Then gradle and maven sources can be generated by triggering annotations:

@GenerateGradlePlugin(
    namePrefix = "Test",
    micronautPlugin = false,
    types = {
        Type.GRADLE_TASK,
        Type.GRADLE_EXTENSION,
        Type.GRADLE_SPECIFICATION,
        Type.GRADLE_PLUGIN
    },
    tasks = {
        @GenerateGradleTask(
            namePrefix = "GenerateSimpleRecord",
            extensionMethodName = "generateSimpleRecord",
            source = "io.micronaut.sourcegen.example.plugin.GenerateSimpleRecordTask"
        ),
        @GenerateGradleTask(
            namePrefix = "GenerateSimpleResource",
            extensionMethodName = "generateSimpleResource",
            source = "io.micronaut.sourcegen.example.plugin.GenerateSimpleResourceTask"
        )
    }
)
public final class GeneratePluginTrigger {
}
@GenerateMavenMojo(
    namePrefix = "AbstractGenerateSimpleRecord",
    micronautPlugin = false,
    source = "io.micronaut.sourcegen.example.plugin.GenerateSimpleRecordTask",
    mavenPropertyPrefix = "test.generate.simple.record"
)
@GenerateMavenMojo(
    namePrefix = "AbstractGenerateSimpleResource",
    micronautPlugin = false,
    source = "io.micronaut.sourcegen.example.plugin.GenerateSimpleResourceTask",
    mavenPropertyPrefix = "test.generate.simple.resource"
)
public final class GenerateMojoTrigger {
}

This generates Gradle plugin, extension, specifications and tasks. For maven it generates maven mojos.
Test suite provides a more complete example.

Gradle extension and maven mojos are extended with implementation-specific details and also tests are shown.

Copy link
Contributor

@melix melix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fairly impressive work already! I haven't performed a full review yet, only tried to understand the basics. What would probably help is some unit tests which assert the generated sources: currently the test suite projects use the generated code, but we can't "see" it so it's hard to tell how "correct" the generated code is. For example, this generates plugin code, but I'd like to understand better how well it integrates.

@andriy-dmytruk
Copy link
Contributor Author

@melix Yes, you are right. I added some simple tests that verify the generated sources

settings.gradle.kts Outdated Show resolved Hide resolved
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
9 Security Hotspots
0.0% Coverage on New Code (required ≥ 70%)
14 New Critical Issues (required ≤ 0)
7 New Bugs (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@graemerocher
Copy link
Contributor

can you address the Sonar failures?

@dstepanov
Copy link
Collaborator

Could you move this to a different project? I don't think we should put everything related to the source generation to this project.

@graemerocher
Copy link
Contributor

good point, might make sense in a new project.

@andriy-dmytruk
Copy link
Contributor Author

Closing in favor of micronaut-projects/micronaut-build-plugin-sourcegen#2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants