Mistuke / GhcChoco

Chocolatey sources for pure GHC installs
https://chocolatey.org/packages/ghc
MIT License
4 stars 1 forks source link

Interaction with haskell-language-server #14

Closed jneira closed 3 years ago

jneira commented 3 years ago

Hi, i would like to bring in a recent reddit comment:

Well, i am afraid that it will be difficult to keep in sync ghc new versions with hls and many other tools and libraries, specially for a major version change with lot of breaking changes, like 9.0.1

  • hls through ghcide is strongly tied to ghc and it suffers specially changes in its internal api
  • hls has a lot of dependencies and all of them should be adapted to the new version before we can start our adaptation process (i've started a wip branch to try to make progress asap) But we need make the new version available through all possible ways, including chocolatey, to help make the adaptation faster. So it is a tricky scenario.

    One possible solution I considered was along the lines of the HLS repo having a file containing supported GHC versions, and the Chocolatey script could be altered to download only versions in that file, or something like that.

That is a nice idea, ghcup (a tool used to install ghc, cabal and hls in linux and osx) has the concept of "recommended version" and i think it still has 8.10.4 as the recommended one. I will open an issue in the choco ghc installer about. In our side we have planned add hls to chocolatey, and ideally it should install all the necessary tools with the appropiate versions (not sure if it is even feasible): https://github.com/haskell/haskell-language-server/issues/1250

Maybe it is asking for too much as i know there are lot of users using chocolatey that dont use hls so make the version supported by hls the preferred one in any way could bother them.

Maybe adding haskell-language-server to chocolatey and use transitively the appropiate version https://chocolatey.org/packages/haskell-dev would be the best solution?

Mistuke commented 3 years ago

Hi,

Maybe it is asking for too much as i know there are lot of users using chocolatey that dont use hls so make the version supported by hls the preferred one in any way could bother them.

Unfortunately there's no control over this. The default version is determined as the highest version that is not a pre-release. Chocolatey follows NuGets versioning scheme https://docs.microsoft.com/en-us/nuget/concepts/package-versioning

Maybe adding haskell-language-server to chocolatey and use transitively the appropiate version https://chocolatey.org/packages/haskell-dev would be the best solution?

Yeah, that would be the best way, as it can declare the dependency on what it needs. You'd also need a constraint on ghc with a specific version so that the dependency solver forces a particular version of GHC for haskell-dev which currently is set to just pick latest available.

The original plan I had was to add a haskell-dev-ide that would come with a pre-configured vscode instance along with (at that time HIE), but compilation of HIE was enough of a pain that I didn't proceed..

Having HSL as a package would allow something like that to more easily be made quite trivially.

jneira commented 3 years ago

Many thanks, i'll try to work on add hls as a choco package, but never did it before :worried: I'll take your work as source of inspiration :smile:

Mistuke commented 3 years ago

Many thanks, i'll try to work on add hls as a choco package, but never did it before 😟

HSL should be a pretty easy package. It's just a single binary if I understood correctly?

I'll take your work as source of inspiration πŸ˜„

Feel free to hit me up with any questions. You can also reach me on irc (Phyx-) but I look maybe 2-3x a day atm :)

jneira commented 3 years ago

After reading chocolatey docs the first sketch i've been able to think of is:

Maye it is not feasible given chocolatey constraints or not very usable. :worried: Ideally we should use GhcChoco and CabalChoco (or HaskellDevChoco), not sure if we could choose the ghc version as params to select the correct version of any of them. could we call the appropiate package installer with args inside the install ps script?

Mistuke commented 3 years ago

After reading chocolatey docs the first sketch i've been able to think of is:

  • create a package haskell-language-server
  • create one version per hls version (and no for each combination of the matrix hls version * ghc version)
  • use --params='/ghc:8.8.1' to:

    • download the hls appropiate ghc version
    • check for ghc-x.y.z.exe in path (or ghc --version?) and ask user to install it if it is not present (force download with specific param or use -y)
    • use a default ghc version if param not set (ghc-8.10.4 for now)

Hmm why do you need this? isn't each HSL version tied to a GHC version? You can just declare GHC as a dependency on the package and give it an explicit version, say

<dependency id="ghc" version="[8.4, 8.6)" />

To accept any 8.4 version.

  • check for cabal in path and ask user to install it if it is not present (force download with specific param or use -y)

Cabal you get by just having a dependency on GHC. You should assume that if a user installs HSL through chocolatey that they are using the entire "ecosystem". i.e. that GHC and Cabal got installed through it as well.

  • same for msys2?

Does HSL require msys2? otherwise I'd just leave it. If it does, add a constraint to haskell-dev along side the ghc one. The constrain solver (like cabal) should work things out for you. haskell-dev is set to allow any GHC. so if your package requires a specific GHC, it'll just use that for haskell-dev installs.

  • install the required extensions in vscode if present

Yeah that would have to be a custom step.

Maye it is not feasible given chocolatey constraints or not very usable. 😟

It should be, but I think you have you dependencies in reverse in this proposal.

Ideally we should use GhcChoco and CabalChoco (or HaskellDevChoco), not sure if we could choose the ghc version as params to select the correct version of any of them.

See above, you should just provide enough constraints for the constraint solver picks the right combination of packages.

could we call the appropiate package installer with args inside the install ps script?

You can, but shouldn't need to. The dependencies take versions. You should think of it as specifying package bounds in a cabal file.

jneira commented 3 years ago

Many thanks for your help.

Hmm why do you need this? isn't each HSL version tied to a GHC version?

Unfortunately it is, we have several executables per hls version: hls-1.0.0-8.10.4.exe, hls-1.0.0-8.8.4.exe and so on for all ghc supported versions. So if we set [8.6.4, 8.10.4) (didnt know choco takes ranges!) for the ghc dependency in hls, could users choose the desired ghc version when installing hls in a way the hls package itself can choose the appropiate hls executable to download?

Cabal you get by just having a dependency on GHC. You should assume that if a user installs HSL through chocolatey that they are using the entire "ecosystem". i.e. that GHC and Cabal got installed through it as well. It should be, but I think you have you dependencies in reverse in this proposal.

Oh, i've just seen https://github.com/Mistuke/GhcChoco/blob/master/9.0.1/ghc/ghc.nuspec#L54. I missed it entirely.

Does HSL require msys2? otherwise I'd just leave it.

It does not require it directly. I added i cause you need it to build packages with cabal that requires configure. But i see the cabal package assumes user will install it So if cabal is fine hls will be too, i guess πŸ™‚

Mistuke commented 3 years ago

Many thanks for your help.

Hmm why do you need this? isn't each HSL version tied to a GHC version?

Unfortunately it is, we have several executables per hls version: hls-1.0.0-8.10.4.exe, hls-1.0.0-8.8.4.exe and so on for all ghc supported versions.

Aha, I thought each version was bound to one :)

So if we set [8.6.4, 8.10.4) (didnt know choco takes ranges!) for the ghc dependency in hls, could users choose the desired ghc version when installing hls in a way the hls package itself can choose the appropiate hls executable to download?

Yes that would be easy to do, the constraint on the package should tell it which one it works with. For instance the earlier cabal choco packages bundled both the 32-bit and 64-bit binaries in the same package, but installed one based on what it detected.

The question however is, do you want to support installing multiple versions when the user has multiple versions of GHC installed side by side? That's slightly harder.

The one thing I am not so sure about is what happens if the user has GHC 9.0.1 installed and then tries to install hsl which supports only up to GHC 8.10.2. One of two things can happen:

I'm expecting the first but we'd need to check.

Does HSL require msys2? otherwise I'd just leave it.

It does not require it directly. I added i cause you need it to build packages with cabal that requires configure. But i see the cabal package assumes user will install it So if cabal is fine hls will be too, i guess πŸ™‚

Most people will also have it through haskell-dev. So I wouldn't worry about it :)

Mistuke commented 3 years ago

install the required extensions in vscode if present

So once you have an HSL package I'd appreciate your help (if you're willing of course) to make haskell-dev-ide which adds a dependency on vscode,

the idea is that when a user does choco install haskell-dev-ide you get a full haskell dev environment set up for Haskell dev in an IDE.

But I confess that I don't really use an IDE that way so having someone who knows more about what users want would be helpful :)

jneira commented 3 years ago

Yes that would be easy to do, the constraint on the package should tell it which one it works with. For instance the earlier cabal choco packages bundled both the 32-bit and 64-bit binaries in the same package, but installed one based on what it detected.

Taking a look to CabalChoco sources i guess that was done through the $env:ChocolateyForceX86 env var. But i am looking in choco documentation for a way to determine what version of upstream packages has been selected with no luck. Otoh i am looking there how users can select a specific version for upstream dependant packages with ranges (someting like cabal's --contraint="ghc == 8.8.4") and i did not found anything 😟

The question however is, do you want to support installing multiple versions when the user has multiple versions of GHC installed side by side? That's slightly harder.

That would be nice, actual hls users have got used to have several ghc versions and their correlated hls executables. In fact hls has a executable, haskell-language-server-wrapper, that choose the appropiate haskell-language-server-${ghcVersion} at runtime examining the project or file at hand. So the idea is to have in PATH all possible hls-${ghcVersion}.exe users could use.

I am afraid that the direct solution would be create several packages for each hls version: hls-1.0.0.0-8.10.4, hls-1.0.0.0-8.8.4 and hls-1.0.0.0-8.6.5. Not sure if that version scheme is acceptef by chocolatey.

the idea is that when a user does choco install haskell-dev-ide you get a full haskell dev environment set up for Haskell dev in an IDE.

Such a integral package would be really nice, i will help in what i can

jneira commented 3 years ago

I am afraid that the direct solution would be create several packages for each hls version: hls-1.0.0.0-8.10.4, hls-1.0.0.0-8.8.4 and hls-1.0.0.0-8.6.5. Not sure if that version scheme is accepted by chocolatey.

Afaiu from choco docs that verson scheme won't be valid: https://chocolatey.org/courses/creating-chocolatey-packages/naming-description-and-versioning#package-versioning

Mistuke commented 3 years ago

I am afraid that the direct solution would be create several packages for each hls version: hls-1.0.0.0-8.10.4, hls-1.0.0.0-8.8.4 and hls-1.0.0.0-8.6.5. Not sure if that version scheme is accepted by chocolatey.

Afaiu from choco docs that verson scheme won't be valid: https://chocolatey.org/courses/creating-chocolatey-packages/naming-description-and-versioning#package-versioning

No, I wouldn't go down that road. If you are publishing the package on chocolatey I would just assume the entire Haskell ecosystem was installed through chocolatey.

In which case you can script the output of choco list --local-only --exact ghc --all-versions which would tell you which versions the user has installed.

This would allow you to know which versions of hls you need to install. This has the condition that if the user installs new versions of GHC they would have to re-install hls. Now they would have had to do do this anyway for new GHC.

That would be nice, actual hls users have got used to have several ghc versions and their correlated hls executables. In fact hls has a executable, haskell-language-server-wrapper, that choose the appropiate haskell-language-server-${ghcVersion} at runtime examining the project or file at hand. So the idea is to have in PATH all possible hls-${ghcVersion}.exe users could use.

With the above you can do this through Chocolatey's shim generations. I generally try not to modify PATH if I can avoid it to keep search time down and avoid accidental shared lib exposures.

jneira commented 3 years ago

No, I wouldn't go down that road. If you are publishing the package on chocolatey I would just assume the entire Haskell ecosystem was installed through chocolatey.

That is the key i was mising, thanks for guiding me into chocolatey universe πŸ™‚

jneira commented 3 years ago

The chocolatey package for haskell-language-server lives!: https://community.chocolatey.org/packages/haskell-language-server

Many thanks again to @Mistuke for all the help. 😸

Mistuke commented 3 years ago

Yay! 😁 Nice!