Skip to content

Commit 537fb88

Browse files
authored
fix: exclude standalone examples from mise run format (#1931)
## Summary - `mise run format` (i.e. `spotless:apply`) fails on JDK 25+ because standalone example POMs don't inherit the spotless plugin from the project parent, but are pulled into the reactor via the `examples-and-integration-tests` profile - Fix: use the fully-qualified plugin goal with profile deactivation - Add `lint:example-poms` check to catch this class of issue Relates #1927 (comment) ## Test plan - [x] `mise run format` succeeds - [x] `lint:example-poms` passes with the fix - [x] `lint:example-poms` fails when reverting the fix --------- Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
1 parent b9906c1 commit 537fb88

File tree

3 files changed

+89
-3
lines changed

3 files changed

+89
-3
lines changed

.mise/tasks/lint/example-poms.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
3+
# [MISE] description="Verify standalone example POMs won't break spotless"
4+
5+
"""Check that standalone example modules don't break 'mise run format'.
6+
7+
Example modules are intentionally standalone (no <parent> from the project)
8+
so users can copy them. But they're included in the Maven reactor via the
9+
examples-and-integration-tests profile. If 'mise run format' doesn't
10+
exclude them, spotless:apply fails because the plugin isn't declared.
11+
12+
This lint verifies that every standalone example POM is excluded from
13+
the format task in mise.toml.
14+
"""
15+
16+
import re
17+
import sys
18+
from pathlib import Path
19+
20+
ROOT = Path(__file__).resolve().parents[3]
21+
EXAMPLES_DIR = ROOT / "examples"
22+
23+
24+
def find_standalone_example_poms() -> list[Path]:
25+
"""Find example pom.xml files that don't inherit from the project parent."""
26+
standalone = []
27+
for pom in sorted(EXAMPLES_DIR.rglob("pom.xml")):
28+
if "target" in pom.parts:
29+
continue
30+
text = pom.read_text(encoding="utf-8")
31+
# Check if this POM has a <parent> with the project's groupId/artifactId
32+
has_project_parent = bool(
33+
re.search(
34+
r"<parent>\s*<groupId>io\.prometheus</groupId>\s*"
35+
r"<artifactId>client_java</artifactId>",
36+
text,
37+
)
38+
)
39+
if not has_project_parent:
40+
standalone.append(pom)
41+
return standalone
42+
43+
44+
def format_task_excludes_examples() -> bool:
45+
"""Check that the format task in mise.toml excludes standalone examples."""
46+
mise_toml = ROOT / "mise.toml"
47+
text = mise_toml.read_text(encoding="utf-8")
48+
# Look for the format task run command
49+
match = re.search(r'\[tasks\.format\].*?run\s*=\s*"([^"]*)"', text, re.DOTALL)
50+
if not match:
51+
return False
52+
run_cmd = match.group(1)
53+
# The command should deactivate the examples-and-integration-tests profile
54+
return "!examples-and-integration-tests" in run_cmd
55+
56+
57+
def main() -> int:
58+
standalone = find_standalone_example_poms()
59+
if not standalone:
60+
return 0
61+
62+
if format_task_excludes_examples():
63+
return 0
64+
65+
print("ERROR: Standalone example POMs found but 'mise run format'")
66+
print("does not exclude the examples-and-integration-tests profile.")
67+
print()
68+
print("Standalone example POMs (no project parent):")
69+
for pom in standalone:
70+
print(f" {pom.relative_to(ROOT)}")
71+
print()
72+
print("Fix: ensure the format task in mise.toml deactivates the")
73+
print("examples-and-integration-tests profile, e.g.:")
74+
print(" -P '!examples-and-integration-tests'")
75+
return 1
76+
77+
78+
if __name__ == "__main__":
79+
sys.exit(main())

AGENTS.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ mise run test-all
2323

2424
# Format code with Google Java Format
2525
mise run format
26-
# or directly: ./mvnw spotless:apply
2726

2827
# Run a single test class
2928
./mvnw test -Dtest=CounterTest \
@@ -143,6 +142,12 @@ mise run lint
143142
# or to autofix: mise run fix
144143
```
145144

145+
### Before Pushing
146+
147+
**ALWAYS** run `mise run lint` before pushing to verify
148+
all lints pass. CI runs the same checks and will fail
149+
if any lint is violated.
150+
146151
## Testing
147152

148153
- JUnit 5 (Jupiter) with `@Test` annotations

mise.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ env.PROTO_GENERATION = "true"
2020

2121
[tasks.format]
2222
description = "format source code"
23-
run = "./mvnw spotless:apply"
23+
# Use fully-qualified plugin goal and deactivate the examples-and-integration-tests
24+
# profile because standalone example modules don't inherit the spotless plugin.
25+
run = "./mvnw com.diffplug.spotless:spotless-maven-plugin:apply -P '!examples-and-integration-tests'"
2426

2527
[tasks.clean]
2628
description = "clean all modules"
@@ -65,7 +67,7 @@ file = "https://raw.githubusercontent.com/grafana/flint/0ac131d7832bd8964f6ca9e5
6567

6668
[tasks."lint"]
6769
description = "Run all lints"
68-
depends = ["lint:super-linter", "lint:links", "lint:bom", "lint:renovate-deps"]
70+
depends = ["lint:super-linter", "lint:links", "lint:bom", "lint:example-poms", "lint:renovate-deps"]
6971

7072
[tasks.fix]
7173
description = "Auto-fix lint issues"

0 commit comments

Comments
 (0)