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

Issue 215: Use API defaults for a simpler experience #235

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

brunovieira97
Copy link
Contributor

@brunovieira97 brunovieira97 commented Jan 21, 2024

New setting to allow for Spring Initializr recommended defaults to be used for following configurations:

  • Spring Boot version
  • Language
  • Packaging
  • Java version

Setting: spring.initializr.useApiDefaults*
Type: boolean
Default value: false


The default values will be based on the default field from API's response, such as below:

"javaVersion": {
    "type": "single-select",
    "default": "17",
    "values": [
        {
            "id": "21",
            "name": "21"
        },
        {
            "id": "17",
            "name": "17"
        }
    ]
}

If there's a default value set via existing configurations such as defaultJavaVersion, then those take precedence over the API recommendation.

If the API response does not contain a default value for a property, then the existing behavior applies and the extension prompts the user to select one.

Closes #215

@brunovieira97
Copy link
Contributor Author

I looked at my previous commits and realized they were not signed, for some reason. Had to force-push to fix that.

@brunovieira97
Copy link
Contributor Author

@jdneo @testforstephen this PR has been waiting for a review for quite a while, could you take a look?

@testforstephen testforstephen self-assigned this Aug 30, 2024
const items = await serviceManager.getItems(projectMetadata.serviceUrl, MetadataType.BOOTVERSION);

if (projectMetadata.enableSmartDefaults === true) {
projectMetadata.bootVersion = items.find(x => x.default === true)?.value?.id;
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should guard the case of projectMetadata.bootVersion is null, and fall back to the prompt mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed that for every API default. Thanks!

@testforstephen
Copy link
Collaborator

I prefer to use the configured default values for spring.initializr.defaultJavaVersion, spring.initializr.defaultLanguage, spring.initializr.defaultPackaging in settings.json first if they exist. If not, then use the API recommended default values.

@brunovieira97
Copy link
Contributor Author

@testforstephen regarding the use of already present default* settings, that is my objective as well: each step starts by fetching the configured default and uses that. If there's no configured default, and enableSmartDefaults = true, it will use the API recommendation.

At least that's my goal in this example from SpecifyJavaVersionStep:

const javaVersion: string = projectMetadata.defaults.javaVersion || workspace.getConfiguration("spring.initializr").get<string>("defaultJavaVersion");

if (javaVersion) {
    projectMetadata.javaVersion = javaVersion;
    // this finishes the step execution and uses the default set by user with already existing configuration
    return true;
}

const items = await serviceManager.getItems(projectMetadata.serviceUrl, MetadataType.JAVAVERSION);

if (projectMetadata.enableSmartDefaults === true) {
    projectMetadata.javaVersion = items.find(x => x.default === true)?.value?.id;
    // new code: use the api default if existing default configuration is not set
    return true;
}

Improvement idea

Perhaps a better name for the setting would be useApiRecommendations or useApiDefaults. Then, the setting documentation could be updated such as:

Use default values provided by Spring Initializr API for Spring Boot version, language, Java version and packaging. Configured defaults for each property take precedence over this setting.

Let me know what you think! And I appreciate any additional feedback, of course.

@testforstephen
Copy link
Collaborator

testforstephen commented Sep 19, 2024

Since we already allow users to specify default value for certain settings (such as Java version, language packing), and won't display them in the Creation Wizard if specified, this approach might be enough. One concern with relying on the API's default values is the lack of transparency and predictability. It's not clear to me that which default values are being applied, and these defaults may change over time.

@testforstephen
Copy link
Collaborator

Add @martinlippert (the lead of the spring tools) for comments, what do you think of the user experience in this PR?

@martinlippert
Copy link

Using defaults from the API makes sense to me. The overall sequence of picking the default values seems good to me as well:

  1. pick value from the preferences (if specified)
  2. pick value from the API

We could also think about remembering the selected values (in the same way we do this for the selected dependencies).

A difficult part here is to have up-to-date values in the preference dialog. At the moment, the values are extremely outdated (take a look at the java version drop down, for example). So it would be best if we could dynamically define the values for the drop downs in the preferences ans populate them with choices from the API.

Another overall difficulty here is that we need to make sure that - whatever the API decides the default values should be - the overall IDE experience should nicely support (e.g. the version of Java). If - for example - the API decides to switch to Kotlin as the preferred language (I don't see that coming, but just as an example here), we should not show that as the default value in the IDE for as long as we don't have good Kotlin language tooling in Code.

@brunovieira97
Copy link
Contributor Author

Thanks for the comments, @testforstephen and @martinlippert!

Firstly, I agree with the order for the preferences, that should be the result of this PR.

Remembering last used values for packaging, Java version and etc should be possible, but I believe a separate PR would be more appropriate for such change.

As for the outdated recommendations in the extension settings, those are statically set in the package.json file. I'm not aware of a way to update them dynamically. Regarding the API recommendations, filter the options based on Code support would be a bit tricky. And I guess it'd involve regular manual updates on the codebase. Nevertheless, it's probably worth it to explore the possibilities in a separate PR.

For now, based on my current free time, I would like to limit this PR only to using the API defaults on an opt-in basis. I will also change the setting name to spring.initializr.useApiDefaults as said before. What do you think, @testforstephen?

As the API does not change drastically too often, there is time to explore the discussed improvements later, and I'll be glad to open additional PRs if I'm able to.

@testforstephen
Copy link
Collaborator

For now, based on my current free time, I would like to limit this PR only to using the API defaults on an opt-in basis. I will also change the setting name to spring.initializr.useApiDefaults as said before.

Yes, please go ahead. We need to rename the setting to give more clarification on what it does.

As for the outdated recommendations in the extension settings, those are statically set in the package.json file. I'm not aware of a way to update them dynamically.

We can write a utility js for this task, and run the script to automatically update the package.json with the new API values. This script doesn't need to be integrated into the CI job and can be run manually on a periodic basis.

@brunovieira97
Copy link
Contributor Author

Hello, @testforstephen. Just pushed the change I mentioned. Guess that's it for this PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Apply smart defaults to project creation wizard
3 participants