vscode-spring-initializr icon indicating copy to clipboard operation
vscode-spring-initializr copied to clipboard

Issue 215: Use API defaults for a simpler experience

Open brunovieira97 opened this issue 1 year ago • 10 comments
trafficstars

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 avatar Jan 21 '24 17:01 brunovieira97

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

brunovieira97 avatar Feb 09 '24 15:02 brunovieira97

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

brunovieira97 avatar Aug 29 '24 21:08 brunovieira97

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.

testforstephen avatar Sep 14 '24 05:09 testforstephen

@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.

brunovieira97 avatar Sep 14 '24 13:09 brunovieira97

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 avatar Sep 19 '24 04:09 testforstephen

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

testforstephen avatar Sep 19 '24 06:09 testforstephen

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.

martinlippert avatar Sep 19 '24 10:09 martinlippert

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.

brunovieira97 avatar Sep 22 '24 17:09 brunovieira97

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.

testforstephen avatar Sep 25 '24 05:09 testforstephen

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

brunovieira97 avatar Sep 25 '24 21:09 brunovieira97