commercialhaskell / stack

The Haskell Tool Stack
http://haskellstack.org
BSD 3-Clause "New" or "Revised" License
3.98k stars 843 forks source link

Provide binaries for `haskell-language-server` #6617

Open sol opened 2 months ago

sol commented 2 months ago

Reading through https://github.com/commercialhaskell/stack/blob/d9165e1cfc7a7738145f122f34466d0fa5b9835f/doc/Stack_and_VS_Code.md this sounds complicated and error prone.

Stack already provides GHC binaries and I think if Stack were to provide corresponding haskell-language-server binaries for each version of GHC, this could make things much more robust.

In an ideal world a sub command, e.g. stack lsp would start a language server, taking care of all the details.

In a second step https://github.com/neovim/nvim-lspconfig, https://github.com/haskell/vscode-haskell, etc. could then be updated to make use of stack lsp.

Note that personally I don't have a need for stack lsp myself, but I do have a need for the haskell-language-server binaries. I have a use case where I use stack to install versions of GHC and I'm going to need corresponding haskell-language-server binaries.

hasufell commented 2 months ago

Using stack with ghcup is not error prone at all.

GHCup will make sure that GHC and HLS are ABI compatible, which is non-trivial.

A few caveats:

This is already the case when you configure stack to use the ghcup install hook (you're asked during ghcup bootstrap if you want to do so).

Additionally, ghcup has an interface to correctly build HLS from source (now even in the TUI).

What's the reason to duplicate this effort?

sol commented 2 months ago

@hasufell thanks for chiming in.

What's the reason to duplicate this effort?

I want the option to produce statically linked binaries that are self-contained and I'm not prepared to consider (L)GPL3 dependencies at this point. That's why I originally decided on using stack to manage GHC versions.

Before going into technical stuff, are you in principle willing to consider relicensing (parts of) ghcup under MIT, BSD2 or BSD3?

now even in the TUI

That's nice, but I think not essential when you want to produce consistent environments programmatically. That's what I am doing, and I think that's what stack needs.

If you want to stick with LGPL3 for ghcup itself, maybe it could be an option to move some of the less UI centric code into a separate dependency (e.g. ghcup-core) that then can be shared between ghcup and stack.

Another benefit of this approach would be a smaller dependency footprint for ghcup-core, and by extension fewer transitive dependencies for users of ghcup-core.

hasufell commented 2 months ago

want the option to produce statically linked binaries that are self-contained and I'm not prepared to consider (L)GPL3 dependencies at this point.

I don't think you'll be linking against ghcup in any way. Stack doesn't either. It invokes ghcup the binary.

I don't see how that causes licensing issues.

sol commented 2 months ago

I want the option to produce statically linked binaries that are self-contained

@hasufell I emphasized the relevant part of my original reply 😉 I hope that makes more sense now. If not, then please let me know and I'm happy to clarify.

hasufell commented 2 months ago

Yeah. Your answer is unclear.

If you want a statically linked HLS, then that's actively discouraged (issues with TH and internal linker... we don't link dynamically for fun).

Using ghcup in a toolchain that produces statically linked binaries is a non-issue in terms of license.

sol commented 2 months ago

If you want a statically linked HLS, then that's actively discouraged

Yeah, that makes sense of course. If I were linking statically against HLS, then I would not need a tool to manage HLS versions.

Let me reiterate my use case:

I use stack to install versions of GHC and I'm going to need corresponding haskell-language-server binaries.

Specifically, I'm using stack as a library.

EDIT: So for my specific use case, what I'm looking for is a library that can manage GHC versions and corresponding HLS versions. This could either be stack (the status quo), ghcup, or ideally some shared dependency between stack and ghcup (say ghcup-core).

hasufell commented 2 months ago

Specifically, I'm using stack as a library.

You still haven't explained how that causes licensing issues with ghcup.

Stack the library executes a shell hook that it knows nothing about. That shell hook may execute ghcup or anything else. Stack doesn't know. Executing a binary doesn't make you subject to LGPL.

sol commented 2 months ago

Before going into technical stuff, are you in principle willing to consider relicensing (parts of) ghcup under MIT, BSD2 or BSD3?

@hasufell to value your and my time, and to keep this issue focused, can I get your perspective on this?

hasufell commented 2 months ago

Before going into technical stuff, are you in principle willing to consider relicensing (parts of) ghcup under MIT, BSD2 or BSD3?

@hasufell to value your and my time, and to keep this issue focused, can I get your perspective on this?

My perspective depends on the use case.

I can not see a case where LGPL is a problem, since no one ever has linked against GHCup the library.

sol commented 2 months ago

Before going into technical stuff, are you in principle willing to consider relicensing (parts of) ghcup under MIT, BSD2 or BSD3?

@hasufell to value your and my time, and to keep this issue focused, can I get your perspective on this?

My perspective depends on the use case.

That's great! Does this mean that if somebody wanted to use ghcup as a library then that would be something you would be willing to consider? E. g. Doing something along the lines of:

If you want to stick with LGPL3 for ghcup itself, maybe it could be an option to move some of the less UI centric code into a separate dependency (e.g. ghcup-core) that then can be shared between ghcup and stack.

At least from my perspective reducing this code duplication, where it makes sense, could be beneficial to all parties.

A nice benefit here would be, that if you were to use both stack and ghcup "provided" GHCs with cabal-install for some reason you could profit from a shared cabal store without running into issues due to ABI incompatibilities, because both GHC's would be exactly the same, and hence by definition ABI compatible. While this is not a big problem for most users, it's something that would benefit me at least (I am using ghcup for most regular development, but stack provided GHCs for a scripting environment that I'm working on).

hasufell commented 2 months ago

That's great! Does this mean that if somebody wanted to use ghcup as a library then that would be something you would be willing to consider?

It's a lot of work. I'd have to contact all code contributors. So it depends.

Right now there is code duplication between ghcup and stack for managing GHC versions.

Yes, that's tracked here: https://github.com/haskell/ghcup-hs/issues/719

A nice benefit here would be, that if you were to use both stack and ghcup "provided" GHCs with cabal-install for some reason you could profit from a shared cabal store without running into issues due to ABI incompatibilities, because both GHC's would be exactly the same, and hence by definition ABI compatible. While this is not a big problem for most users, it's something that would benefit me at least (I am using ghcup for most regular development, but stack provided GHCs for a scripting environment that I'm working on).

I find this a bit hard to understand.

But I think there may be some assumptions that are not true.

E.g. stack and ghcup will not magically pick the same GHC bindist. Stack inspects the system (e.g. ldconfig -p output), while ghcup relies on reading /etc/os-release. That can lead to very different decisions.

However, ghcup allows to use stack's setup-info metadata and will then switch to stack's bindist selection logic.

Both strategies can be seen here: https://github.com/haskell/ghcup-hs/blob/master/lib/GHCup/Platform.hs