Skip to content

Commit 496b66a

Browse files
author
Björn Ekryd
committed
Added an AGENTS file for code and project guidelines
1 parent 886e7fa commit 496b66a

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

AGENTS.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# SortPom — Coding Guidelines for AI Agents
2+
3+
## Project Overview
4+
5+
SortPom is a Maven plugin that sorts `pom.xml` files. It is a two-module Maven project:
6+
7+
- **`sorter/`** — Core sorting library (pure business logic, no Maven dependencies)
8+
- **`maven-plugin/`** — Maven plugin wrapper around the sorter
9+
10+
## Build & Tooling
11+
12+
```bash
13+
mvn verify # Full build: compile, test, integration tests
14+
mvn test # Unit tests only
15+
mvn fmt:format # Auto-format all Java source (Spotify fmt-maven-plugin)
16+
mvn fmt:check # Verify formatting without modifying files
17+
```
18+
19+
Always run `mvn fmt:format` before committing, or let it run as part of the build. Code that fails the format check will break CI.
20+
21+
Integration tests live in `maven-plugin/src/it/` and are executed via `maven-invoker-plugin` during `verify`.
22+
23+
## Java Version
24+
25+
- Current target: **Java 17** (`maven.compiler.release=17`)
26+
- Use `var` for local variable type inference where it improves readability (it is widely used in this codebase)
27+
- Java 17 features are available: sealed classes, pattern matching for `instanceof`, records, text blocks
28+
- Do not use language features beyond Java 17
29+
30+
## Code Style
31+
32+
Formatting is enforced automatically by `fmt-maven-plugin` (Google Java Format). Do not manually adjust whitespace or brace placement — just run `mvn fmt:format`.
33+
34+
**Naming:**
35+
- Classes: `PascalCase`
36+
- Methods and fields: `camelCase`
37+
- Constants: `UPPER_SNAKE_CASE`
38+
- Packages: lowercase, e.g. `sortpom.wrapper.content`
39+
40+
**Javadoc:** Add Javadoc to public classes and non-trivial public methods. Include `@author` on classes only where already present in the file.
41+
42+
**Annotations:** Use `@SuppressWarnings` sparingly and only with justification.
43+
44+
## Architecture
45+
46+
The codebase is layered; keep concerns separated:
47+
48+
| Layer | Location | Responsibility |
49+
|---|---|---|
50+
| Plugin (Mojo) | `maven-plugin/.../SortMojo`, `VerifyMojo`, `AbstractParentMojo` | Maven lifecycle, parameter wiring |
51+
| Application | `sorter/.../SortPomImpl`, `SortPomService` | Orchestration |
52+
| Domain | `sorter/.../wrapper/`, `sorter/.../verify/` | Sorting logic, XML structure |
53+
| Infrastructure | `sorter/.../util/`, `sorter/.../output/` | File I/O, XML serialisation |
54+
55+
**Key patterns in use:**
56+
- **Builder**`PluginParameters.Builder` for all configuration; use this pattern for new config objects
57+
- **Strategy / Wrapper hierarchy**`Wrapper<T>` implementations define different sort behaviours; add new sorting strategies here
58+
- **Factory**`WrapperFactory` / `WrapperFactoryImpl` creates wrappers; register new wrapper types here
59+
- **Template Method**`HierarchyWrapperOperation` defines the tree traversal hooks
60+
61+
Never mix Maven plugin concerns (Mojo annotations, `MavenProject`) into the `sorter` module.
62+
63+
## Error Handling
64+
65+
- Throw `FailureException` (extends `RuntimeException`) for unrecoverable errors in the sorter module
66+
- The plugin layer converts `FailureException` to `MojoFailureException` via `ExceptionConverter`
67+
- Do not propagate checked exceptions beyond module boundaries
68+
69+
## Testing
70+
71+
**Coverage requirement: 100%.** Every new production code path must have a corresponding test.
72+
73+
### Test frameworks
74+
- JUnit 5 (Jupiter) — `@Test`, `@ParameterizedTest`, etc.
75+
- Mockito 5 — for mocking collaborators
76+
- Hamcrest 3 — preferred for assertions; use `assertThat(actual, matcher)`
77+
- JUnit `Assertions` — acceptable for simple equality (`assertEquals`, `assertTrue`, etc.)
78+
79+
### Test structure
80+
81+
Test classes mirror the production package structure and are named `{Subject}Test`.
82+
83+
For XML sorting tests, use the fluent test utilities rather than constructing objects manually:
84+
85+
```java
86+
// Sorting / round-trip XML tests
87+
XmlProcessorTestUtil.create()
88+
.predefinedSortOrder("recommended_2008_06")
89+
.testInputAndExpected("src/test/resources/MyFeature_input.xml",
90+
"src/test/resources/MyFeature_expected.xml");
91+
92+
// Full integration through SortPomImpl
93+
SortPomImplUtil.create()
94+
.sortDependencies("scope,groupId,artifactId")
95+
.testFiles("src/test/resources/MyFeature_input.xml",
96+
"src/test/resources/MyFeature_expected.xml");
97+
```
98+
99+
XML fixture files live in `sorter/src/test/resources/`. Name them `<Feature>_input.xml` and `<Feature>_expected.xml`.
100+
101+
### What to test
102+
103+
- Normal (happy-path) cases with fixture XML files
104+
- Edge cases: empty elements, comments, processing instructions, special characters
105+
- Error cases: verify `FailureException` is thrown with the correct message
106+
- Parameter validation: invalid combinations should fail with a clear error
107+
108+
### What not to do
109+
110+
- Do not mock the file system or XML parser in integration-style tests; use real fixture files
111+
- Do not use `@BeforeEach` to share mutable state across unrelated tests
112+
- Do not test private methods directly; test through the public API
113+
114+
## Adding New Features
115+
116+
1. Add or update the parameter in `PluginParameters` (and its `Builder`)
117+
2. Wire the parameter through `AbstractParentMojo` if it is user-facing
118+
3. Implement the logic in the sorter module (typically a new `Wrapper` implementation or a new phase in an existing wrapper)
119+
4. Register the wrapper in `WrapperFactoryImpl` if needed
120+
5. Add fixture XML files and tests covering all branches
121+
6. Run `mvn verify` to confirm 100% coverage and passing integration tests

0 commit comments

Comments
 (0)