Skip to content

Commit 99411e7

Browse files
kopporcalixtus
andauthored
Add ADR-0050 on code formatter (#13895)
* Add ADR-0050 * Update custom code style decision with maintenance note Added a note about the Eclipse formatter not being actively maintained. --------- Co-authored-by: Carl Christian Snethlage <[email protected]>
1 parent f3cfa49 commit 99411e7

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
---
2+
nav_order: 50
3+
parent: Decision Records
4+
---
5+
# Use custom code style
6+
7+
## Context and Problem Statement
8+
9+
Code should be formatted consistently.
10+
Which code style and auto formatter to be used?
11+
12+
## Decision Drivers
13+
14+
* Consistency to the Java world (to lower the cognitive load)
15+
* Maintained tooling to reduce risk of non-working tooling in the future
16+
17+
## Considered Options
18+
19+
* Use custom code style
20+
* Use prettier-java
21+
* Use palantir-java-format
22+
* Use google-java-format
23+
* Use spring-javaformat
24+
* Use eclipse formatter
25+
26+
## Decision Outcome
27+
28+
Chosen option: "Use custom code style", because comes out best (see below).
29+
30+
### Consequences
31+
32+
* Good, because the style closely follows the maintainer's expectations on code formatting
33+
* Good, because the IntelliJ tooling works reasonably well
34+
* Bad, because users need to setup IntelliJ to use the code style
35+
36+
## Pros and Cons of the Options
37+
38+
<!-- markdownlint-disable-next-line MD024 -->
39+
### Use custom code style
40+
41+
IntelliJ offers to customize the code style and export it into an XML file.
42+
43+
* Good, because the style closely follows the maintainer's expectations on code formatting
44+
* Good, because the IntelliJ tooling works reasonably well
45+
* Bad, because users need to setup IntelliJ to use the code style
46+
* Bad, because depends on IntelliJ's capabilities (and is not tool-independent)
47+
* Bad, because the statement after `->` is [always on the next line](https://youtrack.jetbrains.com/issue/IDEA-330487/Disable-line-breaks-after-switch-cases-on-simple-on-liner-case-blocks-in-switch-expression).
48+
49+
### Use prettier-java
50+
51+
[prettier-java](https://github.com/jhipster/prettier-java) is a prettier plugin for Java.
52+
53+
It uses around [80 characters as soft width limit](https://prettier.io/docs/options#print-width):
54+
55+
> For readability we recommend against using more than 80 characters:
56+
>
57+
> In code styleguides, maximum line length rules are often set to 100 or 120. However, when humans write code, they don’t strive to reach the maximum number of columns on every line. Developers often use whitespace to break up long lines for readability. In practice, the average line length often ends up well below the maximum.
58+
>
59+
> Prettier’s `printWidth` option does not work the same way. It is not the hard upper allowed line length limit. It is a way to say to Prettier roughly how long you’d like lines to be. Prettier will make both shorter and longer lines, but generally strive to meet the specified `printWidth`.
60+
61+
We tried out at <https://github.com/JabRef/jabref-koppor/pull/717>.
62+
63+
Example:
64+
65+
```java
66+
action
67+
.getKeyBinding()
68+
.ifPresent(keyBinding ->
69+
keyBindingRepository
70+
.getKeyCombination(keyBinding)
71+
.ifPresent(combination -> setAccelerator(combination))
72+
);
73+
```
74+
75+
* Good, because `prettier-java` is updated regularly.
76+
* Good, because the subject is "always" in the first thing in the line.
77+
* Good, because it also formats the imports
78+
* Neutral, because optimized for code review (because of the 80 characters width):
79+
Favors short lines (80 characters); the reading is more top-to-buttom; screens are typically wider.
80+
* Bad, because [prettier-action cannot be used](https://github.com/creyD/prettier_action/issues/149)
81+
* Bad, because [has line breaks at single variables](https://github.com/jhipster/prettier-java/issues/777)
82+
83+
## Use palantir-java-format
84+
85+
Example:
86+
87+
```java
88+
action.getKeyBinding().ifPresent(keyBinding -> keyBindingRepository
89+
.getKeyCombination(keyBinding)
90+
.ifPresent(combination -> setAccelerator(combination)));
91+
```
92+
93+
* Good, because [optimized for code review](https://github.com/palantir/palantir-java-format#optimised-for-code-review)
94+
* Bad, because [not compatible with JDK21](https://github.com/palantir/palantir-java-format/issues/934). Especially, [does not support `_`](https://github.com/palantir/palantir-java-format/issues/1236)
95+
96+
## Use google-java-format
97+
98+
* Bad, because [Markdown JavaDoc cannot be used](https://github.com/google/google-java-format/issues/1193)
99+
* Bad, because [does not support `format:off` comments](https://github.com/google/google-java-format/issues/137).
100+
* Bad, because not actively maintained; there are [139 opened issues](https://github.com/google/google-java-format/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen&page=1).
101+
102+
## Use spring-javaformat
103+
104+
[spring-javaformat](https://github.com/spring-io/spring-javaformat) is a code style of Spring.
105+
The plugin is automatically activated in IntelliJ. For the code style, see <https://github.com/spring-projects/spring-framework/wiki/Code-Style>.
106+
107+
We tried out at <https://github.com/JabRef/jabref-koppor/pull/716>.
108+
109+
* Neutral, because each class field is separated by an empty line:\
110+
111+
![empty lines between class fields](assets/0050-spring-empty-lines.png)
112+
113+
* Bad, because merges lines together where it should not:
114+
115+
![style merges lines](assets/0050-spring-merge.png)
116+
117+
* Bad, because `import` statements are not handled.
118+
* Bad, because we need to accept that `else` starts on the "first" column. ("Kernighan and Ritchie style") -> <https://github.com/spring-projects/spring-framework/wiki/Code-Style#block-like-constructs-kr-style>
119+
* Bad, because it provides bad wrapping:
120+
121+
```diff
122+
/**
123+
- * Add X11 clipboard support to a text input control. It is necessary to call this method in every input where you
124+
- * want to use it: {@code ClipBoardManager.addX11Support(TextInputControl input);}.
125+
- *
126+
- * @param input the TextInputControl (e.g., TextField, TextArea, and children) where adding this functionality.
127+
- * @see <a href="https://www.uninformativ.de/blog/postings/2017-04-02/0/POSTING-en.html">Short summary for X11
128+
- * clipboards</a>
129+
- * @see <a href="https://unix.stackexchange.com/questions/139191/whats-the-difference-between-primary-selection-and-clipboard-buffer/139193#139193">Longer
130+
+ * Add X11 clipboard support to a text input control. It is necessary to call this
131+
+ * method in every input where you want to use it:
132+
+ * {@code ClipBoardManager.addX11Support(TextInputControl input);}.
133+
+ * @param input the TextInputControl (e.g., TextField, TextArea, and children) where
134+
+ * adding this functionality.
135+
+ * @see <a href=
136+
+ * "https://www.uninformativ.de/blog/postings/2017-04-02/0/POSTING-en.html">Short
137+
+ * summary for X11 clipboards</a>
138+
+ * @see <a href=
139+
+ * "https://unix.stackexchange.com/questions/139191/whats-the-difference-between-primary-selection-and-clipboard-buffer/139193#139193">Longer
140+
* text over
141+
```
142+
143+
```diff
144+
- public ArgumentProcessor(String[] args,
145+
- Mode startupMode,
146+
- PreferencesService preferencesService,
147+
- FileUpdateMonitor fileUpdateMonitor,
148+
- BibEntryTypesManager entryTypesManager) throws org.apache.commons.cli.ParseException {
149+
+ public ArgumentProcessor(String[] args, Mode startupMode, PreferencesService preferencesService,
150+
+ FileUpdateMonitor fileUpdateMonitor, BibEntryTypesManager entryTypesManager)
151+
+ throws org.apache.commons.cli.ParseException {
152+
```
153+
154+
## Use eclipse formatter
155+
156+
* Good, because it [can be used in IntelliJ](https://github.com/krasa/EclipseCodeFormatter)
157+
* Bad, because not actively maintained
27.3 KB
Loading
46.4 KB
Loading

0 commit comments

Comments
 (0)