pulumi / pulumi/pulumi-java

`pulumi package gen-sdk --language java` to generate gradle dependency version ranges

Open
#1,926 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/codegen kind/enhancement
Dominant language
Java
Stars
85
Forks
26
Avg merge
11h 49m
Merged PRs (30d)
22

Description

Steps to reproduce

  1. Pick up a Pulumi component or provider.
  2. Run pulumi package gen-sdk provider/cmd/my-provider/schema.json --language java --out sdk/

What should happen?

When opening the build.gradle file, the following default dependencies section should be generated:

dependencies {
    implementation("com.google.code.findbugs:jsr305:[3.0.2,4)")
    implementation("com.google.code.gson:gson:[2.8.9,3)")
    implementation("com.pulumi:pulumi:[1.0.0,2)")
}

Notice that a range is used to specify to specify the compatible dependency versions.

What happens instead?

Versions are pinned:

dependencies {
    implementation("com.google.code.findbugs:jsr305:3.0.2")
    implementation("com.google.code.gson:gson:2.8.9")
    implementation("com.pulumi:pulumi:1.0.0")
}

Why does this matter?

Let's say tomorrow someone discovers a security vulnerability on one of our pulumi-java dependencies. For instance, com.google.code.gson:gson:2.8.9. Since we are pinning to that specific version on our build.gradle file, we will need to re-generate all SDKs to point to the updated version (or alternatively, make our customers override this dependency on their side). Instead, If we had specified our dependency with a version range such as com.google.code.gson:gson:[2.8.9,) and a 2.8.10 security patch version was released, Gradle will automatically pick the updated 2.8.10 patch version when building our customer's code without requiring an SDK code change or our users' intervention.


Some context on how Gradle works (not intuitive to me since I am used to other dependency systems which work different):

Specifying dependency versions in Gradle

When you declare a dependency version using the shorthand notation (meaning just the version), then the version is considered a required version:

[...] the selected version cannot be lower than what require accepts, but it can be higher through conflict resolution, even if the higher version has an exclusive upper bound. This is the default behavior for a direct dependency.

This can be verified by running gradle dependencies and seeing the produced dependency version tree. See for instance, what the following blocks generate:

dependencies {
    implementation('org.slf4j:slf4j-api:1.7.15')
}

Means that the minimum version will be 1.7.15 and it can be optimistically upgraded by the engine. However, if there are no other transitive dependencies that require a version greater than 1.7.15, Gradle will pick 1.7.15 instead of the latest and greatest compatible version.

To achieve getting the latest and greatest compatible version (assuming semver), you should write:

dependencies {
    implementation('org.slf4j:slf4j-api:[1.7.15,)')
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the pulumi package gen-sdk --language java entry point and inspect how it generates build.gradle from provider/cmd/my-provider/schema.json. Update the generated dependency declarations to use the requested Gradle version ranges, then rerun the command and verify the output matches the expected dependencies block.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.