|
| 1 | +--- |
| 2 | +description: Micronaut Development Guide |
| 3 | +author: Cédric Champeau |
| 4 | +version: 1.0 |
| 5 | +globs: ["**/*.java", "**/*.kts", "**/*.xml"] |
| 6 | +--- |
| 7 | + |
| 8 | +# Micronaut Project Development Guide |
| 9 | + |
| 10 | +## Project Overview |
| 11 | + |
| 12 | +This project is a Micronaut module which is part of the Micronaut Framework, a modern, JVM-based, full-stack framework for building modular, easily testable microservice and serverless applications. |
| 13 | + |
| 14 | +The description of what this project is doing can be found in the `gradle.properties` file under the `projectDesc` key. |
| 15 | + |
| 16 | +This repository does not represent an actual application; its modules are designed to be used as dependencies by applications. |
| 17 | +The root project MUST NOT contain any code: it is a parent project which coordinates the build and supplies documentation. |
| 18 | + |
| 19 | +⚠️ CRITICAL: DO NOT USE attempt_completion BEFORE TESTING ⚠️ |
| 20 | + |
| 21 | +## Command Conventions |
| 22 | + |
| 23 | +- You MUST run all Gradle commands (except testing ones) with the quiet option to reduce output: |
| 24 | + - Do NOT use: `--stacktrace`, `--info` (excessive output will not fit the context) |
| 25 | +- You MUST run all Gradle testing commands without the `-q` option, since that will suppress the output result of each test. |
| 26 | +- Gradle project names are prefixed with `micronaut-`. For example, directory `mylib` maps to Gradle project `:micronaut-mylib`. |
| 27 | +- You MUST run Gradle with the Gradle wrapper: `./gradlew`. |
| 28 | +- Gradle project names prefixed with `test-` or `test-suite` are not intended for users: they are functional tests of the project |
| 29 | + |
| 30 | +## Main Development Tasks: |
| 31 | + |
| 32 | +- Compile (module): `./gradlew -q :<module>:compileTestJava` |
| 33 | +- Test (module): `./gradlew :<module>:test` |
| 34 | +- Checkstyle (aggregate task): `./gradlew -q cM` |
| 35 | + - Note: `cM` is the canonical Checkstyle runner defined in build logic to validate Checkstyle across the codebase. |
| 36 | + - Note: you MUST NOT introduce new warnings. You SHOULD fix warnings in code that you have modified. |
| 37 | +- Spotless (check license headers/format): `./gradlew -q spotlessCheck` |
| 38 | +- Spotless (auto-fix formatting/headers): `./gradlew -q spotlessApply` (MUST be used to fix violations found by `spotlessCheck`) |
| 39 | + |
| 40 | +## Code style |
| 41 | + |
| 42 | +You SHOULD prefer modern Java idioms: records, pattern matching, sealed interfaces/classes, `var` for local variables. |
| 43 | +You MUST NOT use fully qualified class names unless there is a conflict between 2 class names in different packages. |
| 44 | +You MUST annotate the code with nullability annotations (`io.micronaut.core.annotation.Nullable`, `io.micronaut.core.annotation.NonNull`). |
| 45 | + |
| 46 | +## Binary compatibility |
| 47 | + |
| 48 | +Micronaut projects are intended to be used in consumer applications and therefore follow semantic versioning. As a consequence: |
| 49 | +- You MUST NOT break any public facing API without explicit consent |
| 50 | +- You SHOULD run the `./gradlew japiCmp` task to get a report about binary breaking changes |
| 51 | +- You SHOULD reduce the visibility of members for non user-facing APIs. |
| 52 | +- You MUST annotate non-user facing APIs with `@io.micronaut.core.annotation.Internal` |
| 53 | + |
| 54 | +## Implementation Workflow (Required Checklist) |
| 55 | + |
| 56 | +You MUST follow this sequence after editing source files: |
| 57 | + |
| 58 | +1) Compile affected modules |
| 59 | + - `./gradlew -q :<module>:compileTestJava :<module>:compileTestGroovy` |
| 60 | + |
| 61 | +2) Run targeted tests first (fast feedback) |
| 62 | + - `./gradlew :<module>:test --tests 'pkg.ClassTest'` |
| 63 | + - `./gradlew :<module>:test --tests 'pkg.ClassTest.method'` (optional) |
| 64 | + |
| 65 | +3) Run full tests for all affected modules |
| 66 | + - `./gradlew :<module>:test` |
| 67 | + |
| 68 | +4) Static checks |
| 69 | + - Checkstyle: `./gradlew -q cM` |
| 70 | + |
| 71 | +5) (Optional) If, and only if you have created new files, you SHOULD run |
| 72 | + - Spotless check: `./gradlew -q spotlessCheck` |
| 73 | + - If Spotless fails: `./gradlew -q spotlessApply` then re-run `spotlessCheck` |
| 74 | + - You MUST NOT add new license headers on existing files: only focus on files you have added |
| 75 | + |
| 76 | +6) Verify a clean working tree |
| 77 | + - You SHOULD ensure no unrelated changes are pending before proposing changes. |
| 78 | + - Use `git_status` to verify the working tree: |
| 79 | + ```xml |
| 80 | + <use_mcp_tool> |
| 81 | + <server_name>mcp-server-git</server_name> |
| 82 | + <tool_name>git_status</tool_name> |
| 83 | + <arguments> |
| 84 | + { |
| 85 | + "repo_path": "/home/cchampeau/DEV/PROJECTS/micronaut/micronaut-langchain4j" // adjust absolute path if necessary |
| 86 | + } |
| 87 | + </arguments> |
| 88 | + </use_mcp_tool> |
| 89 | + ``` |
| 90 | + |
| 91 | +## Documentation Requirements |
| 92 | + |
| 93 | +- You MUST update documentation when necessary, following the project’s documentation rules in `.clinerules/docs.md`. |
| 94 | +- Before writing code, you SHOULD analyze relevant code files to get full context, then implement changes with minimal surface area. |
| 95 | +- You SHOULD list assumptions and uncertainties that need clarification before completing a task. |
| 96 | +- You SHOULD check project configuration/build files before proposing structural or dependency changes. |
| 97 | + |
| 98 | +## Context7 Usage (Documentation and Examples) |
| 99 | + |
| 100 | +You MUST use Context7 to get up-to-date, version-specific documentation and code examples for frameworks and libraries. |
| 101 | + |
| 102 | +Preferred library IDs: |
| 103 | +- Micronaut main docs: `/websites/micronaut_io` |
| 104 | +- Micronaut Test: `/websites/micronaut-projects_github_io_micronaut-test` |
| 105 | +- Micronaut Oracle Cloud: `/websites/micronaut-projects_github_io_micronaut-oracle-cloud` |
| 106 | +- OpenRewrite: `/openrewrite/rewrite-docs` |
| 107 | + |
| 108 | +Example (fetch docs for a topic): |
| 109 | +```xml |
| 110 | +<use_mcp_tool> |
| 111 | + <server_name>context7-mcp</server_name> |
| 112 | + <tool_name>get-library-docs</tool_name> |
| 113 | + <arguments> |
| 114 | + { |
| 115 | + "context7CompatibleLibraryID": "/openrewrite/rewrite-docs", |
| 116 | + "topic": "JavaIsoVisitor" |
| 117 | + } |
| 118 | + </arguments> |
| 119 | +</use_mcp_tool> |
| 120 | +``` |
| 121 | + |
| 122 | +For other libraries, you MUST resolve the library ID first: |
| 123 | +```xml |
| 124 | +<use_mcp_tool> |
| 125 | + <server_name>context7-mcp</server_name> |
| 126 | + <tool_name>resolve-library-id</tool_name> |
| 127 | + <arguments> |
| 128 | + { |
| 129 | + "libraryName": "Mockito" |
| 130 | + } |
| 131 | + </arguments> |
| 132 | +</use_mcp_tool> |
| 133 | +``` |
| 134 | + |
| 135 | +## Dependency Management (Version Catalogs) |
| 136 | + |
| 137 | +- Main dependencies are managed in the Gradle version catalog at `gradle/libs.versions.toml`. |
| 138 | +- You MUST use catalogs when adding dependencies (avoid hard-coded coordinates/versions in module builds). |
| 139 | + |
| 140 | +Adding a new dependency (steps): |
| 141 | +1) Choose or add the version in the appropriate catalog (`libs.versions.toml`). |
| 142 | +2) Add an alias under the relevant section (e.g., `libraries`). |
| 143 | +3) Reference the alias from a module’s `build.gradle.kts`, for example: |
| 144 | + - `implementation(libs.some.library)` |
| 145 | + - `testImplementation(testlibs.some.junit)` |
| 146 | +4) Do NOT hardcode versions in module build files; use the catalog entries. |
| 147 | + |
| 148 | +You SHOULD choose the appropriate scope depending on the use of the library: |
| 149 | + - `api` for dependencies which appear in public signatures or the API of a module |
| 150 | + - `implementation` for dependencies which are implementation details, only used in the method bodies for example |
| 151 | + - `compileOnly` for dependencies which are only required at build time but not at runtime |
| 152 | + - `runtimeOnly` for dependencies which are only required at run time and not at compile time |
| 153 | + |
| 154 | +## Build logic |
| 155 | + |
| 156 | +Micronaut projects follow Gradle best practices, in particular usage of convention plugins. |
| 157 | +Convention plugins live under the `buildSrc` directory. |
| 158 | + |
| 159 | +You MUST NOT add custom build logic directly in `build.gradle(.kts)` files. |
| 160 | +You MUST implement build logic as part of convention plugins. |
| 161 | +You SHOULD avoid build logic code duplication by moving common build logic into custom convention plugins. |
| 162 | +You SHOULD try to prefer composition of convention plugins. |
| 163 | + |
| 164 | +## Key Requirements |
| 165 | + |
| 166 | +You MUST confirm all of the following BEFORE using `attempt_completion`: |
| 167 | + |
| 168 | +- Changes compile successfully (affected modules) |
| 169 | +- Targeted tests pass |
| 170 | +- Full tests for affected modules pass |
| 171 | +- Checkstyle (`cM`) passes |
| 172 | +- Spotless (`spotlessCheck`) passes (apply fixes if needed) |
| 173 | +- Documentation updated when necessary |
| 174 | +- Working tree is clean (no unrelated diffs) |
| 175 | + |
| 176 | +If ANY item is “no”, you MUST NOT use `attempt_completion`. |
0 commit comments