|
| 1 | +# Contributing |
| 2 | + |
| 3 | +This repository contains **PMD jPinpoint rules, unit tests and documentation** (Java + Kotlin). |
| 4 | + |
| 5 | +## General guidelines |
| 6 | + |
| 7 | +A couple of general guidelines that help the review process: |
| 8 | + |
| 9 | +- Create an issue with a clear problem description and add test cases and a solution approach when possible. |
| 10 | +- Align on the applicability, scope and approach before opening a pull request. |
| 11 | +- Please avoid reformatting unrelated code; keep changes limited to the area you’re fixing so the diff stays focused and easier to review. |
| 12 | +- When changing a rule, please add (or update) unit tests that cover the new behavior. |
| 13 | + |
| 14 | +## How to contribute |
| 15 | + |
| 16 | +1. **Open an issue first** |
| 17 | + - Bug report: include version, rule name, minimal reproduction code, and expected vs actual behavior. |
| 18 | + - Rule enhancement / new rule: include examples for **violations** and **no violations**. |
| 19 | + - Please use standard issue title prefixes and include the language: |
| 20 | + - `Fix Request (Java): ...` / `Fix Request (Kotlin): ...` |
| 21 | + - `Rule Request (Java): ...` / `Rule Request (Kotlin): ...` |
| 22 | +2. **Create a branch** from `pmd7` (!) and keep the change focused. |
| 23 | +3. **Update/add unit tests** for the behavior you changed. |
| 24 | +4. **Run tests locally** (`./mvnw clean test`) and ensure they pass. |
| 25 | +5. **Open a pull request** |
| 26 | + - Link the issue. |
| 27 | + - Describe what changed and why. |
| 28 | + - Include notes about any false-positive / false-negative tradeoffs if relevant. |
| 29 | + |
| 30 | +## Development |
| 31 | + |
| 32 | +To start development on the ruleset the PMD tool designer may come in handy. |
| 33 | +Download it from the [PMD project at github](https://pmd.github.io/) and install it using the instructions on their site. |
| 34 | + |
| 35 | +After installation and configuration you can start the designer from the command prompt: |
| 36 | + |
| 37 | +```bash |
| 38 | +pmd.bat designer |
| 39 | +``` |
| 40 | + |
| 41 | +or |
| 42 | + |
| 43 | +```bash |
| 44 | +./pmd designer |
| 45 | +``` |
| 46 | + |
| 47 | +## Build and run tests |
| 48 | + |
| 49 | +The project is built using **Maven**. The build runs the **unit tests** which validate the rules. |
| 50 | + |
| 51 | +From the repository root: |
| 52 | + |
| 53 | +```bash |
| 54 | +./test |
| 55 | +``` |
| 56 | + |
| 57 | +## Adding new rules |
| 58 | + |
| 59 | +You can add new rules using the steps below. |
| 60 | + |
| 61 | +The steps basically tell you to create an issue, add documentation and create 3 files. |
| 62 | +As an example you can copy existing files and change the content according to your needs. |
| 63 | +Always work along the lines of what already exists. |
| 64 | + |
| 65 | +For Kotlin: use the paths that contain `/kotlin/` instead of `/java/`. |
| 66 | + |
| 67 | +- Create an issue like **"Rule Request: AvoidRecreatingExpensiveThing"** with simple compiling examples which can be used as tests. |
| 68 | + Use this issue reference with check-in. |
| 69 | +- Document the pitfall in the proper page and category in `docs/` and |
| 70 | + [regenerate the ToC](https://luciopaiva.com/markdown-toc/). |
| 71 | +- Add the test class in |
| 72 | + `src/test/java/com/.../perf/lang/java/ruleset/yourruleset/YourRule.java`. |
| 73 | + Elements from the package structure are used to lookup the rules XML file you add next. |
| 74 | + The relevant items based on the example given are: `lang/java/ruleset/yourruleset`. |
| 75 | +- Rules go into XML files found in `src/main/resources/category/`. |
| 76 | + In this case: `src/main/resources/category/java/yourruleset.xml`. |
| 77 | + Also add a rule with name `YourRule` since that is what the framework expects. |
| 78 | + For new rule files (a new category) you will also need to register it in the |
| 79 | + `categories.properties` file found in the same directory |
| 80 | + (`category/java/categories.properties`), in this case add `category/java/yourruleset.xml`. |
| 81 | +- Add the unit test in an XML file in |
| 82 | + `src/test/resources/com/.../perf/lang/java/ruleset/yourruleset/xml/YourRule.xml`. |
| 83 | + Pay attention to the package structure which is also dictated by the first Java test class. |
| 84 | + |
| 85 | +Depending on what you want to add you may find it is sufficient to change one or more existing files. |
| 86 | +Or to add only a test class and unit test XML file. |
| 87 | + |
| 88 | +### Conventions for XML unit test files |
| 89 | + |
| 90 | +Following are some conventions and recommendations on how to construct the unit test files: |
| 91 | + |
| 92 | +- Separate test code (create separate `<test-code>` blocks) |
| 93 | +- Specify test code description (`<test-code><description>`). Start the description with: |
| 94 | + - **violation:** or |
| 95 | + - **no violation:** |
| 96 | +- Specify number of occurrences (`<test-code><expected-problems>`) |
| 97 | +- Specify line-numbers (`<test-code><expected-linenumbers>`) |
| 98 | +- Code conventions (`<test-code><code>`): |
| 99 | + - use class names like `Foo` |
| 100 | + - use method names like `bad` and `good` |
| 101 | + - add comment at the end of bad lines `//bad` |
| 102 | + - remove useless code and `import` statements |
| 103 | + |
| 104 | +## Run Kotlin unit tests |
| 105 | + |
| 106 | +When running unit tests for Kotlin, PMD 7 is needed. |
| 107 | +Make sure you have access to the PMD jars of the `7.2.24-SNAPSHOT` branch (e.g. `./mvnw install` the PMD 7.2.x jars from https://github.com/pmd/pmd). |
| 108 | +Use the Maven `kotlin-pmd7` profile when running the Kotlin unit tests. |
| 109 | + |
| 110 | +> Note: use `./mvnw` (the Maven Wrapper) for all builds in this repository. |
| 111 | +
|
| 112 | +## Code style indentation |
| 113 | + |
| 114 | +- Indentation: use spaces (disable tabs): |
| 115 | + *Settings → Editor → Code Style → Java → Use tab character (disable)* |
| 116 | + |
| 117 | +## Contents of the project |
| 118 | + |
| 119 | +- `rulesets/java/jpinpoint-rules.xml` contains the PMD custom rule definitions. |
| 120 | +- `src/main/java/pinpointrules` contains the Java code containing pitfalls for testing the rules. |
| 121 | +- `rulesets-merger` contains the Java code for a ruleset merger tool. |
| 122 | + |
| 123 | +## Merging rules |
| 124 | + |
| 125 | +The merger tool can merge rule categories into a single ruleset file used by IDE plugins. |
| 126 | + |
| 127 | +Build the merger tool: |
| 128 | + |
| 129 | +```bash |
| 130 | +cd rulesets-merger |
| 131 | +./mvnw clean install |
| 132 | +``` |
| 133 | + |
| 134 | +Run the merger tool: |
| 135 | + |
| 136 | +```bash |
| 137 | +cd rulesets-merger |
| 138 | +./mvnw exec:java -Dexec.args="java" |
| 139 | +``` |
| 140 | + |
| 141 | +or simply: |
| 142 | + |
| 143 | +```bash |
| 144 | +./merge |
| 145 | +``` |
| 146 | + |
| 147 | +For Kotlin instead of Java: |
| 148 | + |
| 149 | +```bash |
| 150 | +./merge kotlin |
| 151 | +``` |
| 152 | + |
| 153 | +### Merging with company-specific rules |
| 154 | + |
| 155 | +Company-specific rules are useful for instance for checking the right use of company-specific or company-bought frameworks and libraries. |
| 156 | + |
| 157 | +Copy `rulesets-merger` to your company rules directory and adjust a few constants at the top to make it work for your company. |
| 158 | + |
| 159 | +The merge tool runs for either Java or Kotlin rules. Use the first argument to choose: `java` or `kotlin`. |
| 160 | + |
| 161 | +After building, the merger tool can be run with: |
| 162 | + |
| 163 | +```bash |
| 164 | +cd rulesets-merger |
| 165 | +./mvnw exec:java -Dexec.args="java" |
| 166 | +``` |
| 167 | + |
| 168 | +or simply: |
| 169 | + |
| 170 | +```bash |
| 171 | +./merge |
| 172 | +``` |
| 173 | + |
| 174 | +For Kotlin instead of Java: |
| 175 | + |
| 176 | +```bash |
| 177 | +./merge kotlin |
| 178 | +``` |
| 179 | + |
| 180 | +It will attempt to locate the `PMD-jPinpoint-rules` project next to your own project and merge |
| 181 | +`rulesets/[java|kotlin]/jpinpoint-rules.xml` together with your rule files (from `src/main/resources/category/[java|kotlin]/*.xml`). |
| 182 | + |
| 183 | +It assumes you have repositories in directories next to each other: |
| 184 | + |
| 185 | +```text |
| 186 | +PMD-Company-jPinpoint-rules |
| 187 | +PMD-jPinpoint-rules (optional) |
| 188 | +``` |
| 189 | + |
| 190 | +It will generate: |
| 191 | + |
| 192 | +```text |
| 193 | +company-rules.xml |
| 194 | +company-jpinpoint-rules.xml |
| 195 | +``` |
| 196 | + |
| 197 | +You can also specify the external repo explicitly, e.g.: |
| 198 | + |
| 199 | +```bash |
| 200 | +cd target |
| 201 | +java -jar rulesets-merger-1.0-SNAPSHOT.jar PMD-jPinpoint-rules rulesets/java jpinpoint-rules.xml |
| 202 | +``` |
| 203 | + |
| 204 | +For Kotlin: |
| 205 | + |
| 206 | +```bash |
| 207 | +cd target |
| 208 | +java -jar rulesets-merger-1.0-SNAPSHOT.jar PMD-jPinpoint-rules rulesets/kotlin jpinpoint-rules.xml |
| 209 | +``` |
| 210 | + |
| 211 | + |
0 commit comments