|
| 1 | +--- |
| 2 | +name: run-plugin |
| 3 | +description: Build, test, and release this PaperMC/Spigot plugin from source. Use when asked to build the plugin, run its tests, run a single test class, or produce a release JAR. |
| 4 | +--- |
| 5 | + |
| 6 | +This is a PaperMC/Spigot plugin — "running" it means building from source, executing the test |
| 7 | +suite, and optionally producing the shaded JAR that gets dropped into a server's `plugins/` |
| 8 | +folder. |
| 9 | + |
| 10 | +## Commands |
| 11 | + |
| 12 | +**OneDrive locking**: If the project resides in OneDrive, the build fails with `Unable to delete directory '...\build\test-results\test\binary'`, delete that directory manually before retrying — OneDrive holds a sync lock on it. |
| 13 | + |
| 14 | +```bash |
| 15 | +# Build (runs Checkstyle, SpotBugs, and tests) |
| 16 | +./gradlew build |
| 17 | +``` |
| 18 | + |
| 19 | +### Testing |
| 20 | + |
| 21 | +```bash |
| 22 | +# Run tests only |
| 23 | +./gradlew test |
| 24 | + |
| 25 | +# Run a single test class |
| 26 | +./gradlew test --tests "com.example.plugin.command.PingTest" |
| 27 | + |
| 28 | +# Run a single test method |
| 29 | +./gradlew test --tests "com.example.plugin.command.GreetTest.greetsTarget" |
| 30 | +``` |
| 31 | + |
| 32 | +Checkstyle enforces Google Java style with `maxWarnings = 0` — the build fails on any warning. SpotBugs runs FindSecBugs. Both run as part of `build`; fix all findings before committing. |
| 33 | + |
| 34 | +Command executor unit tests (`Ping`, `Greet`, etc.) use Mockito directly — mock `CommandArguments` and `CommandSender`/`Player`, then call `run()`. No server or plugin lifecycle needed. Mockito must be declared explicitly as `testImplementation 'org.mockito:mockito-core:...'` — it is not provided transitively. |
| 35 | + |
| 36 | +## Release JAR |
| 37 | + |
| 38 | +```bash |
| 39 | +./gradlew -Pver="v1.0.0" release |
| 40 | +# → build/libs/<project-name>.jar (version stripped from filename for stable tags) |
| 41 | +``` |
| 42 | + |
| 43 | +Versioning logic (`build.gradle.kts`): |
| 44 | +- No `-Pver` → `yyMMdd-HHmm-SNAPSHOT` |
| 45 | +- `-Pver=vX.Y.Z-RC-N` → `X.Y.Z-SNAPSHOT` |
| 46 | +- `-Pver=vX.Y.Z` → `X.Y.Z` (stable; the `release` task then renames the shadow jar to |
| 47 | + `${rootProject.name}.jar`) |
| 48 | + |
| 49 | +Quote the `-Pver` value to stop the shell/PowerShell from mangling the `=`. |
| 50 | + |
| 51 | +## Maintenance |
| 52 | + |
| 53 | +After adding a dependency, check whether `shadowJar` in `build.gradle.kts` needs a new |
| 54 | +`relocate(...)` entry (to avoid classloader clashes with other plugins on the same server) and |
| 55 | +a `minimize { exclude(...) }` entry — see the first Gotcha below for why this matters. |
| 56 | + |
| 57 | +Keep these in sync with the current state of the project: |
| 58 | + |
| 59 | +- **`AGENTS.md`** — architecture, versioning logic |
| 60 | +- **`.agents/skills/fill-template-plugin/SKILL.md`** — customization checklist |
| 61 | +- **`README.md`**, **`docs/usage.md`**, **`docs/customization.md`**, **`docs/releases.md`** — |
| 62 | + feature list, extension recipes, fork checklist, PaperMC version mapping |
| 63 | +- **`.agents/skills/run-plugin/SKILL.md`** (this file) — build commands, release |
| 64 | + process, shaded package list |
| 65 | + |
| 66 | +## Gotchas |
| 67 | + |
| 68 | +- **`minimize()` silently strips reflection/SPI-only dependencies** — `shadowJar`'s `minimize()` |
| 69 | + only treats a dependency as "used" if *this project's own compiled classes* reference it |
| 70 | + directly. A library only referenced from inside an already-`exclude`d dependency (e.g. |
| 71 | + cw-commons calling into a JDBC/driver library) looks unused and gets stripped down to empty |
| 72 | + `package-info.class` stubs, causing `NoClassDefFoundError` at runtime even though the build |
| 73 | + succeeds. Add an `exclude(dependency("group:artifact:.*"))` entry under `minimize` for any |
| 74 | + such dependency, mirroring the existing `cw-commons` entry (which works around the same |
| 75 | + problem for its bundled SQLite driver). |
| 76 | +- **OneDrive build lock** — if this repo lives under OneDrive, `./gradlew build` can fail with |
| 77 | + `Unable to delete directory '...\build\classes\java\main'` (or `...\test\binary`, or other |
| 78 | + `build/` subdirectories) because OneDrive holds a sync lock on it. Delete the offending |
| 79 | + directory manually (e.g. `rm -rf build/classes/java/main`) and retry. |
| 80 | +- **Commands declared in both `plugin.yml` and `onEnable()`** — CommandAPI registers commands |
| 81 | + programmatically; don't add a matching `commands:` entry to `plugin.yml` or Bukkit |
| 82 | + double-registers it, which CommandAPI flags at startup with a warning. |
| 83 | +- **Mockito javaagent** — `mockito-core` is wired into a dedicated `mockitoAgent` configuration |
| 84 | + and attached via `-javaagent` in `tasks.test` to avoid the inline-mock-maker self-attach |
| 85 | + warning. Don't drop this wiring when customizing the template, and remember Mockito must stay |
| 86 | + declared explicitly as `testImplementation` — it isn't provided transitively. |
0 commit comments