Authoritative source: IntelliJCodeStyle.xml at the repo root (import it into
your IDE). The rules below summarise what matters when editing by hand.
USE_TAB_CHARACTER = true,
SMART_TABS = true). Tab width is 4, continuation indent is 8.}.PascalCase. Concrete implementations of an interface use an
Impl suffix where the codebase already does (P4PasswordImpl,
ManualWorkspaceImpl, AutoCleanImpl, CommitImpl).camelCase. Constants: UPPER_SNAKE_CASE.isXxx() (e.g. isTidy()), other getters getXxx().java.util.logging.Logger:
private static final Logger logger = Logger.getLogger(MyClass.class.getName());
(Some older classes declare it non-final as private static Logger logger;
prefer private static final for new code but match the file you're in.)
Data-bound config object:
@DataBoundConstructor
public MyThing(String required) { this.required = required; }
@DataBoundSetter
public void setOptional(boolean optional) { this.optional = optional; }
Put required fields in the @DataBoundConstructor; add optional/new
fields via @DataBoundSetter so old saved configs still deserialize.
@Deprecated overloads that delegate to the new one
(see UnshelveBuilder for the established pattern) — never break binary/config
compatibility for a published plugin.@Extension public static class DescriptorImpl extends ...Descriptor, annotated with @Symbol("pipelineName") for Pipeline.doCheckXxx(...) returns FormValidation,
doFillXxxItems(...) returns ListBoxModel.edu.umd.cs.findbugs.annotations.@NonNull /
@CheckForNull — SpotBugs (spotbugs:check) gates the build.mvn spotbugs:check must pass. Suppress a genuine false positive narrowly with
@SuppressFBWarnings("PATTERN") and a reason, rather than disabling broadly.# Java Style & Formatting
Authoritative source: `IntelliJCodeStyle.xml` at the repo root (import it into
your IDE). The rules below summarise what matters when editing by hand.
## Indentation — tabs, not spaces
- Indentation uses **hard tab characters** (`USE_TAB_CHARACTER = true`,
`SMART_TABS = true`). Tab width is 4, continuation indent is 8.
- **Never** introduce spaces for indentation. Mixing spaces in a tab-indented
file is the most common formatting mistake here — match the surrounding lines
exactly (copy an existing line's leading whitespace if unsure).
- Applies to Java, Groovy, HTML, and Jelly. JSON uses 2-space tabs.
## Imports
- **No wildcard / on-demand imports.** The threshold is set absurdly high
(50 classes / 10 names), so every import is listed explicitly.
- Don't reorder or "optimise" imports in files you aren't otherwise changing.
## Blank lines & braces
- At most one consecutive blank line inside declarations and code.
- No blank line directly before a closing `}`.
- Opening brace on the same line (K&R), standard for the codebase.
## Naming
- Classes: `PascalCase`. Concrete implementations of an interface use an
`Impl` suffix where the codebase already does (`P4PasswordImpl`,
`ManualWorkspaceImpl`, `AutoCleanImpl`, `CommitImpl`).
- Methods/fields: `camelCase`. Constants: `UPPER_SNAKE_CASE`.
- Boolean getters use `isXxx()` (e.g. `isTidy()`), other getters `getXxx()`.
## Logging
- Use `java.util.logging.Logger`:
```java
private static final Logger logger = Logger.getLogger(MyClass.class.getName());
```
(Some older classes declare it non-final as `private static Logger logger`;
prefer `private static final` for new code but match the file you're in.)
## Jenkins / Stapler idioms (follow these patterns)
- Data-bound config object:
```java
@DataBoundConstructor
public MyThing(String required) { this.required = required; }
@DataBoundSetter
public void setOptional(boolean optional) { this.optional = optional; }
```
Put **required** fields in the `@DataBoundConstructor`; add **optional/new**
fields via `@DataBoundSetter` so old saved configs still deserialize.
- Keep old constructors as `@Deprecated` overloads that delegate to the new one
(see `UnshelveBuilder` for the established pattern) — never break binary/config
compatibility for a published plugin.
- Descriptors are a nested `@Extension public static class DescriptorImpl
extends ...Descriptor`, annotated with `@Symbol("pipelineName")` for Pipeline.
- Form helpers live on the descriptor: `doCheckXxx(...)` returns `FormValidation`,
`doFillXxxItems(...)` returns `ListBoxModel`.
- Annotate nullability with `edu.umd.cs.findbugs.annotations.@NonNull` /
`@CheckForNull` — SpotBugs (`spotbugs:check`) gates the build.
## Static analysis
- `mvn spotbugs:check` must pass. Suppress a genuine false positive narrowly with
`@SuppressFBWarnings("PATTERN")` and a reason, rather than disabling broadly.
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 33896 | Sandeep Kumar | Add unit test to increase code covreage. |