Skip to content

Commit db42626

Browse files
committed
Add the Style and About pages
Style describes the one layout the formatter produces: wrapping, lambdas, call chains, long strings, imports and comments, and three trade-offs. Every Java block on it was run through a build of the formatter and comes back unchanged, so the page shows output rather than intent. Two things came out differently from the old README the material came from: a chain is split only when everything before its last dot passes 80 columns, and before splitting the formatter first tries moving the whole chain to the next line; Javadoc and block comments are left as written, while line comments are wrapped. The trade-offs name the $NON-NLS$ markers that end up on another line, with the formatter's output as the example. About says where the formatter is published, that the Maven Central artifacts and the GitHub release files come from the release workflow, as the 2.98.0.1 run shows, and how to check a download. The release key's fingerprint and the import command were checked against keys.openpgp.org, and the signature of the 2.98.0.1 checksum file verifies with it. Planned work is pointed at the issues, because the roadmap left the formatter's README.
1 parent 51c051f commit db42626

3 files changed

Lines changed: 219 additions & 0 deletions

File tree

‎docs/about.md‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# About
2+
3+
open-java-format is a Java formatter developed in the open. It began as a fork of
4+
palantir-java-format, which is itself a fork of google-java-format, and every artifact is now built
5+
and published from [its own repository](https://github.com/openjavaformat/open-java-format). Why the
6+
project exists is in the [manifesto](manifesto.md).
7+
8+
## Where it is published
9+
10+
| Where | What |
11+
| --- | --- |
12+
| [Maven Central](https://central.sonatype.com/namespace/dev.openjavaformat) | `dev.openjavaformat:open-java-format`, with `-spi`, `-native` and `-jdk-bootstrap` |
13+
| [Gradle Plugin Portal](https://plugins.gradle.org/plugin/dev.openjavaformat.java-format) | `dev.openjavaformat.java-format` |
14+
| [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/34359-open-java-format) | the IntelliJ IDEA plugin |
15+
| [GitHub Releases](https://github.com/openjavaformat/open-java-format/releases/latest) | native binaries, the runnable jar, the IntelliJ IDEA and Eclipse plugins |
16+
17+
The Maven Central artifacts and the files of a GitHub release are built by the
18+
[release workflow](https://github.com/openjavaformat/open-java-format/blob/main/.github/workflows/release.yml)
19+
from the tag of the version.
20+
21+
## Verify a download
22+
23+
Each file of a GitHub release has a `.asc` signature next to it, and so does each artifact on Maven
24+
Central. They are made with the project's release key:
25+
26+
``` text
27+
13A6 BDF2 DAA9 8D3D 573B 33EA 1004 81FD AEE9 4DE9
28+
```
29+
30+
The key is published on [keys.openpgp.org](https://keys.openpgp.org). Import it once, then check the
31+
checksum file of a release, and the checksum file against your download as shown on the
32+
[Command line](get-started/command-line.md#verify-the-download) page.
33+
34+
``` sh
35+
curl -sSL https://keys.openpgp.org/vks/v1/by-fingerprint/13A6BDF2DAA98D3D573B33EA100481FDAEE94DE9 | gpg --import
36+
gpg --verify checksums_sha256.txt.asc checksums_sha256.txt
37+
```
38+
39+
A good signature ends with the fingerprint above. gpg also warns that the key is not certified with a
40+
trusted signature, because nobody in your keyring has signed it: compare the fingerprint instead.
41+
42+
## Licence
43+
44+
open-java-format is distributed under the
45+
[Apache License 2.0](https://github.com/openjavaformat/open-java-format/blob/main/LICENSE), like
46+
palantir-java-format and google-java-format, and it keeps the copyright notices of both. Neither
47+
Palantir Technologies Inc. nor Google LLC endorses, sponsors or is affiliated with it.
48+
49+
## Take part
50+
51+
- Report a bug or propose a change in the
52+
[issues](https://github.com/openjavaformat/open-java-format/issues), where planned work is tracked
53+
too.
54+
- Every page of this site has an **Edit this page** button, which opens a pull request against
55+
[its sources](https://github.com/openjavaformat/docs).

‎docs/style.md‎

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Style
2+
3+
open-java-format has one style and no settings. It is the style of palantir-java-format 2.x, which
4+
grew out of google-java-format: lines of up to 120 characters, 4 spaces for each level of
5+
indentation, and 8 more for a line that continues a statement. Every example on this page is the
6+
formatter's own output.
7+
8+
## Wrapping
9+
10+
When a declaration does not fit on one line, its parameters move to a continuation line together.
11+
12+
``` java
13+
class Params {
14+
public static ResolvedConfiguration resolveConfigurationForProject(
15+
Project project, String configurationName, boolean includeTransitiveDependencies) {
16+
return resolve(project, configurationName, includeTransitiveDependencies);
17+
}
18+
}
19+
```
20+
21+
## Lambdas
22+
23+
A lambda starts on the line of the call it is passed to, and its body is indented by one level from
24+
that line, however deeply the call is nested.
25+
26+
``` java
27+
class Tasks {
28+
void register(Project project) {
29+
project.getTasks().register("formatDiff", FormatDiffTask.class, task -> {
30+
task.setGroup("formatting");
31+
task.setDescription("Formats the lines you changed");
32+
});
33+
executor.submit(() -> {
34+
runChecks();
35+
});
36+
}
37+
}
38+
```
39+
40+
A short lambda stays on the line of its call, also inside a chain.
41+
42+
``` java
43+
class Lambda {
44+
private static GradleException notFound(String group, String name, Configuration configuration) {
45+
String actual = configuration.getIncoming().getResolutionResult().getAllComponents().stream()
46+
.map(ResolvedComponentResult::getModuleVersion)
47+
.map(mvi -> String.format("\t- %s:%s:%s", mvi.getGroup(), mvi.getName(), mvi.getVersion()))
48+
.collect(Collectors.joining("\n"));
49+
return new GradleException(actual);
50+
}
51+
}
52+
```
53+
54+
The [home page](index.md#what-the-output-looks-like) shows the same kind of code next to the output
55+
of google-java-format.
56+
57+
## Call chains
58+
59+
A chain of calls stays on one line only if everything before its last dot fits in 80 columns, even
60+
when the whole statement would fit in 120. Otherwise each call goes on a line of its own, which keeps
61+
builders and streams easy to read and to diff.
62+
63+
``` java
64+
class Chains {
65+
void f() {
66+
var request = HttpRequest.newBuilder()
67+
.uri(uri)
68+
.header("Accept", "application/json")
69+
.timeout(timeout)
70+
.build();
71+
var user = User.builder().name(name).email(email).build();
72+
}
73+
}
74+
```
75+
76+
On one line the first statement would be 118 characters long, with its last dot in column 110. The
77+
last dot of the second one is in column 58.
78+
79+
When moving the whole chain onto the next line brings its last dot within the limit, the formatter
80+
does that instead of splitting it.
81+
82+
``` java
83+
class Chains {
84+
void f() {
85+
var foo =
86+
SomeType.builder().thing1(thing1).thing2(thing2).thing3(thing3).build();
87+
}
88+
}
89+
```
90+
91+
## Long strings
92+
93+
A string literal that runs past column 120 is split between words, and the rest continues after a
94+
`+` on the next line. On the command line, `--skip-reflowing-long-strings` turns this off.
95+
96+
``` java
97+
class Strings {
98+
String message =
99+
"The formatter reflows a string literal that runs past the column limit, and it keeps the words intact"
100+
+ " while doing so.";
101+
}
102+
```
103+
104+
## Imports
105+
106+
Static imports come first, then a blank line and the other imports, each group in ASCII order.
107+
Imports the file does not use are removed: the input of this example also imported `java.util.Map`
108+
and `java.util.Set`. On the command line, `--skip-sorting-imports` and
109+
`--skip-removing-unused-imports` turn these off.
110+
111+
``` java
112+
package com.example;
113+
114+
import static java.util.Objects.requireNonNull;
115+
116+
import com.google.common.collect.ImmutableList;
117+
import java.util.List;
118+
119+
class Imports {
120+
List<String> names = ImmutableList.of(requireNonNull("a"));
121+
}
122+
```
123+
124+
## Comments
125+
126+
A `//` comment that runs past column 120 is wrapped onto a new `//` line. Javadoc and `/* */`
127+
comments are kept exactly as written, however long their lines are.
128+
129+
``` java
130+
class Comments {
131+
// A line comment that runs past the limit of one hundred and twenty characters is wrapped, and the rest continues
132+
// on a line of its own.
133+
int x;
134+
135+
/** Javadoc is kept exactly as it is written, however long its lines are, because the formatter does not reflow it. */
136+
int y;
137+
}
138+
```
139+
140+
## Trade-offs
141+
142+
- **The layout follows the syntax.** The formatter does not know which grouping of arguments reads
143+
best. When a layout comes out awkward, a local variable or a small method usually fixes it, and the
144+
fix holds on every later run.
145+
- **A `$NON-NLS$` marker can end up on another line.** Eclipse expects the marker on the line of the
146+
string it marks. When the formatter wraps such a statement, the string moves to a line of its own
147+
and the marker stays at the end of the statement:
148+
149+
``` java
150+
class Messages {
151+
void f() {
152+
label.setText(Messages.format(
153+
"The configuration of the project could not be read",
154+
projectName,
155+
configurationFileName)); // $NON-NLS-1$
156+
}
157+
}
158+
```
159+
160+
- **Layout fixes of our own wait for 3.x.** For the whole 2.x line the output is byte-for-byte the
161+
same as the palantir-java-format release with the same version number. The
162+
[manifesto](manifesto.md) explains why output stability comes first.

‎zensical.toml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ nav = [
2626
{ "GitHub Action and pre-commit" = "get-started/github-actions.md" },
2727
] },
2828
{ "AI agents" = "ai-agents.md" },
29+
{ "Style" = "style.md" },
2930
{ "Library rules" = [
3031
"library-rules/index.md",
3132
{ "Flogger" = "library-rules/flogger.md" },
3233
] },
3334
{ "Migrate" = "migrate.md" },
3435
{ "Manifesto" = "manifesto.md" },
36+
{ "About" = "about.md" },
3537
]
3638

3739
# extra_css = ["stylesheets/extra.css"]

0 commit comments

Comments
 (0)