Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a simple nullaway wrapper plugin #2382

Merged
merged 13 commits into from
Sep 15, 2022
Merged

Conversation

carterkozak
Copy link
Contributor

This plugin can be applied with the baseline-error-prone plugin, it adds a standardized nullaway configuration to the project with centrally managed nullaway versioning via gralde-baseline. Note that Nullaway is applied at WARNING rather than ERROR such that projects that already enforce warnings will fail builds on nullaway, however the nullaway warnings will only produce console churn otherwise.

==COMMIT_MSG==
Implement a simple nullaway wrapper plugin com.palantir.baseline-null-away
==COMMIT_MSG==

This plugin can be applied with the baseline-error-prone plugin,
it adds a standardized nullaway configuration to the project with
centrally managed nullaway versioning via gralde-baseline.
Note that Nullaway is applied at `WARNING` rather than `ERROR` such
that projects that already enforce warnings will fail builds on
nullaway, however the nullaway warnings will only produce console
churn otherwise.
@changelog-app
Copy link

changelog-app bot commented Sep 14, 2022

Generate changelog in changelog/@unreleased

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

Implement a simple nullaway wrapper plugin com.palantir.baseline-null-away which registers the NullAway check at WARNING. Projects which fail on warnings will require this to pass pre-merge.

Check the box to generate changelog(s)

  • Generate changelog entry

- org.checkerframework.dataflow.qual.Pure
- org.checkerframework.dataflow.qual.Pure$Kind
- org.checkerframework.dataflow.qual.SideEffectFree
- org.checkerframework.dataflow.qual.TerminatesExecution
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This roughly matches the baseline-class-uniqueness failures in baseline-error-prone. Seems fine, especially for build-only code.

}

private static void configureErrorProneOptions(Project proj, Action<ErrorProneOptions> action) {
proj.afterEvaluate(new Action<Project>() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit gross, but required due to the way the errorprone plugin configures JavaCompile tasks. At this point it may be simpler to implement the errorprone plugin ourselves (now that the errorprone-javac dep isn't needed, and we support jdk11+)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does errorprone also use afterEvaluate? If so just note that the order multiple afterEvaluates run is technically undefined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this may not be necessary here, I'm not entirely sure why it was required in another plugin we worked on recently. I'll remove the afterEvaluate.

Copy link
Contributor

@schlosna schlosna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall seems reasonable, but have a concern about version pins

configureErrorProneOptions(project, new Action<ErrorProneOptions>() {
@Override
public void execute(ErrorProneOptions options) {
options.option("NullAway:AnnotatedPackages", "com.palantir");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we need to provide a default package to make this work out of the box per https://github.com/uber/NullAway/wiki/Configuration#annotated-packages so this seems reasonable, though any non-Palantir projects would need to override this to enable NullAway for their code.

It would be nice to include some other commonly used packages like com.google.common for Guava but that may require more opt-in work for folks adopting this from the get-go per the "Nullness annotations" bits from Guava 31.0 release specifically the NullAway bits mentioning google/guava#6126 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to add guava by default for now, it's easier to remove packages than add them.

I'd considered introspecting the maven coordinate group, and adding something like the first two segments. So net.ckozak.foo would result in net.ckozak as an annotated package. However, I think there are sufficiently many edge cases that I'd prefer to punt solving this until we need to do so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kicked off https://github.com/palantir/tritium/compare/ds/guava-nullaway?expand=1 as a quick check last night and that build failed so I think adding Guava here might cause more false positives than desired by default, so we probably do want just options.option("NullAway:AnnotatedPackages", "com.palantir"); for now. Sorry for the run around on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, I appreciate that you called out the idea! I had just tested a snapshot on tritium and found the same thing :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

palantir/tritium#1570 to fix up tritium's one flagged issue

# See the License for the specific language governing permissions and
# limitations under the License.
#
implementation-class=com.palantir.baseline.plugins.BaselineNullAway
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we haven't switched over to the gradle plugin-publish 1.0 yet on this repo, as this would need to go in the gradlePlugin implementationClass

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have, but the two definition locations are merged, and likely out of sync. This is allowed due to duplicatesStrategy 'include' declared here:

tasks.named('processResources').configure {
duplicatesStrategy 'include'
}

I've created an issue to follow-up and migrate to the gradle-plugin definition-site: #2384

versions.props Outdated
@@ -15,6 +15,8 @@ com.googlecode.java-diff-utils:diffutils = 1.3.0
com.puppycrawl.tools:checkstyle = 10.3.2
org.checkerframework:* = 3.23.0
com.palantir.gradle.utils:* = 0.1.0
com.uber.nullaway:nullaway = 0.10.1
org.checkerframework:dataflow-nullaway = 3.25.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this more specific version pin compared to above?

Suggested change
org.checkerframework:dataflow-nullaway = 3.25.0
org.checkerframework:dataflow-nullaway = 3.25.0

versions.props Outdated
@@ -15,6 +15,8 @@ com.googlecode.java-diff-utils:diffutils = 1.3.0
com.puppycrawl.tools:checkstyle = 10.3.2
org.checkerframework:* = 3.23.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we bump this to 3.25.0 and remove the pin below (and maybe sort these)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the dependency upgrade excavator is stuck, good catch! I agree that we shouldn't pin a more specific version, keeping these in sync is helpful.

versions.lock Outdated
Comment on lines 72 to 74
org.checkerframework:checker-qual:3.23.0 (3 constraints: 08256088)
org.checkerframework:dataflow-errorprone:3.23.0 (4 constraints: fa3d685c)
org.checkerframework:dataflow-nullaway:3.25.0 (2 constraints: 6911b8f1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below, but the mix of 3.23.0 and 3.25.0 versions seems potentially problematic.

.orElseGet(() -> {
log.warn("BaselineNullAway is using 'latest.release' - "
+ "beware this compromises build reproducibility");
return "latest.release";
Copy link
Contributor

@CRogers CRogers Sep 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When does this ever happen? How is nullaway applied?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same logic used in baseline-error-prone. This happens when running integration tests from source, when the classpath is built up of class files rather than a jar with an Implementation-Version in the manifest.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do most jars like google's own error prone core jar have this manifest usually, or is this something we publish?

Copy link
Contributor Author

@carterkozak carterkozak Sep 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is used so that we can publishToMavenLocal prior to running tests, then resolve our own checks from the mavenLocal() repo to test them.

@Override
public void apply(Project project) {
project.getPluginManager().withPlugin("com.palantir.baseline-error-prone", _unused0 -> {
project.getPluginManager().withPlugin("java-base", _unused1 -> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated from java to java-base as I believe that's more general

bulldozer-bot bot pushed a commit to palantir/witchcraft-api that referenced this pull request Sep 15, 2022
###### _excavator_ is a bot for automating changes across repositories.

Changes produced by the roomba/latest-baseline-oss check.

# Release Notes
## 4.164.0
| Type | Description | Link |
| ---- | ----------- | ---- |
| Improvement | The `CyclomaticComplexity` check is now configured with `switchBlockAsSingleDecisionPoint`. | palantir/gradle-baseline#2383 |


## 4.165.0
| Type | Description | Link |
| ---- | ----------- | ---- |
| Improvement | Implement a simple nullaway wrapper plugin `com.palantir.baseline-null-away` which registers the `NullAway` check at `WARNING`. Projects which fail on warnings will require this to pass pre-merge. | palantir/gradle-baseline#2382 |


## 4.166.0
_Automated release, no documented user facing changes_


To enable or disable this check, please contact the maintainers of Excavator.
This was referenced Sep 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants