sdkman / sdkman-cli

The SDKMAN! Command Line Interface
https://sdkman.io
Apache License 2.0
6.08k stars 629 forks source link

Feature: Add command `sdk env default` #1235

Open narko opened 1 year ago

narko commented 1 year ago

Feature request Add the possibility of making every candidate/version pair available in .sdkmanrc as the default version. This will avoid issues when other scripts that run in different shells require the same environment.

martin-braun commented 2 months ago

I came here to feature request this, too. The reason for it is simple: Android Studio's lack of proper support.

Although Android Studio reports that it found the .sdkmanrc and loaded it, its Gradle will still be configured to JAVA_HOME. So in order to have Android Studio point to the same version for Gradle that is referenced in .sdkmanrc, only changing JAVA_HOME will help.

A rather unsatisfying bypass, but straight forward it is to just change the default Java version and setup Android Studio to use JAVA_HOME. I can live with that, but this bypass is even more painful, because I have to copy the version from the .sdkmanrc and paste it in my terminal after sdk default java.

sdk env default would make this much more convenient to deal with. I don't want to rely on JetBrains to fix their bloated mess of an IDE. I doubt this will happen anytime soon.

My nasty alias work-around:

alias sdku='{ f() { sdk env && sdk default $1 $(sdk current $1 | tail -n 1 | cut -d" " -f4); }; }; f'

Then I can just sdku java, but terrible solution.

marc0der commented 2 months ago

Hi both, I must be misunderstanding the issue that you are both experiencing.

The idea with SDKMAN is that you have default versions that will be set for every new shell. This is system-wide. We have a further ability to override these defaults with use, which can be set on a per-terminal basis. The env command should pick up the values in your .sdkmanrc and use those in the current shell. It should never tamper with the system-wide default versions.

@narko can you also please explain what you mean by the following?

This will avoid issues when other scripts that run in different shells require the same environment.

martin-braun commented 2 months ago

Hello @marc0der, thanks for getting in touch regarding the issue. We do know that default is system-wide. We are asking for giving sdk env a new sub command default, so that we can use a .sdkmanrc to change the version system-wide.

Yes, you heard that right and I know it sounds counter-intuitive. Sadly, this is necessary for me due to Android Studio not properly supporting the .sdkmanrc.

This will avoid issues when other scripts that run in different shells require the same environment.

What he means is when he opens new shells, he doesn't want to sdk env again. I don't support that statement, though. However, in the case of Android Studio, it's very annoying.

I do sdk env, followed by studio . to open the project in Android Studio from the shell on macOS. Also Android Studio is consuming the .sdkmanrc for the picked JDK used for building, but not for gradle itself. The problem is their gradle JDK configuration want's me to pick a version and there is no option to simply tell it to use the version from the .sdkmanrc so I have to pick JAVA_HOME and change my default version before-hand:

image

In order to do so I now have to do sdk default java xxxxx before I launch studio . which requires me to read the .sdkmanrc by hand. Only then my JAVA_HOME points to the right version and I can simply use JAVA_HOME for the Gradle JDK. I want a system-wide switch without having to read the .sdkmanrc and sdk env default would make this work.

You probably say now "This is not an issue with SDKMAN!, it's an issue with Android Studio" and I absolutely agree with you. Do I have time to wait for a huge company to fix their massive product that gate-keeps most of their stuff through obscurity and complexity and is lazy in supporting third-party tooling? I'm not sure about that. I mean, I cannot even report this issue without making a JetBrain's account. I don't really like that company, you probably can tell by this point.

What would be your point of view with this issue when it comes to my certain problem? I feel we have to work around their mis-management in that regard.

narko commented 2 months ago

@marc0der it has been a while since I had this problem, but @martin-braun described the exact same need I had back then with Android Studio / Gradle.

marc0der commented 2 months ago

Hey guys, thanks for explaining that so well. I now have a better understanding of what you are grappling with.

You probably say now "This is not an issue with SDKMAN!, it's an issue with Android Studio" and I absolutely agree with you.

I feel your frustration here, but at the same time, I don't think we should introduce such a feature for a relatively niche use case. My even bigger concern is that such a feature would confuse the users of the env command, and it will open the door for using SDKMAN in ways that it's not intended (i.e. clouding the meaning of what a default version is vs how to use a version in the current shell).

My suggestion would be to write a small script, call it defaults.sh, that would read the .sdkmanrc file and invoke the default command for each entry in the file. That's fairly simple to do in bash, and you could even use the source code of env as inspiration. You might even be able to reuse some of the underlying support functions that env calls.

I hope this helps, and if you do decide to do as I suggested above, please post your findings here to help others faced with this problem.

martin-braun commented 2 months ago

@marc0der A small script? That's exactly what my "nasty alias" work-around already does, but I agree a dedicated script that reads the file entirely and filters out only java would be much better, my work around only works if java= is in the first line.

Alternatively, could I propose that we have the ability to print the current java version without the noise?

Imagine, I could do:

sdk env
sdk default java $(sdk current java -v)

It would be so much cleaner for a little alias and it would work with multiple entries in the .sdkmanrc. Right now, sdk current java prints "Using java version 17.0.11-jbr". Maybe we could add a flag -v to sdk current that allows to print only the version (as shown in the above example), this would allow us to skip the necessity to parse the .sdkmanrc ourselves.

I hope you can agree that I want to avoid re-inventing the wheel by copying SDKMAN!'s scripts to do the same. Less is more, we need more simplicity in our life.

marc0der commented 2 months ago

Yes, that seems like a fair tradeoff. I'm due to rewrite the current command in Rust next, so I could accommodate a special flag that only prints out the version. It will probably be --version, but let's see.

martin-braun commented 2 months ago

@marc0der Thanks a lot for this tool and your collaboration on that matter. --version instead of -v, since the latter might imply --verbose? Maybe an additional short-hand -V would be nice instead? But even if not, just having --version alone would already be sufficient as a trade-off.

You changed my way I work with Java-related projects for the better! ❤️