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

Pin versions of libraries used by plugins #2894

Closed
mitchellwrosen opened this issue May 3, 2022 · 12 comments
Closed

Pin versions of libraries used by plugins #2894

mitchellwrosen opened this issue May 3, 2022 · 12 comments
Labels
CI Continuous integration documentation level: easy The issue is suited for beginners type: enhancement New feature or request

Comments

@mitchellwrosen
Copy link

mitchellwrosen commented May 3, 2022

Problem: it is unclear which versions of plugins (the Haskell ones, anyway - I'm not sure if any plugins are not bundled Haskell libraries, but are instead communicated with via subprocess) my HLS has installed.

Describe the solution you'd like

Plugins pin their dependency on the underlying tool (e.g. hls-ormolu-plugin-1.0.2.1 could depend on ormolu == 0.4.0.0 rather than ormolu >= 0.1.2 && < 0.5)

Additional context

This (I think) would make it easier for different people on a team to end up installing a version of HLS that has the same underlying formatter (and other plugins).

Currently, someone I'm collaborating with has managed to install haskell-language-server-1.7.0.0 with a version of ormolu less than the latest 0.4.0.0, which is what my haskell-language-server-1.7.0.0 seems to have picked. So, we're getting some formatting diffs when we trade pull requests. 🥲

@pepeiborra
Copy link
Collaborator

Can't you just use cabal freeze and check in the freeze file?

@mitchellwrosen
Copy link
Author

If there was a freeze file checked into this repo, that would effectively achieve the same result.

Just to clarify - by "you" do you mean "you, Mitchell", or "one"?

@michaelpj
Copy link
Collaborator

It sounds like your underlying problem is a variant of #411 ?

@michaelpj
Copy link
Collaborator

FWIW I solve this problem at work by building HLS from source and adding constraints: stylish-haskell==<whatever>. So then you know your team is all using the same stuff.

@michaelpj michaelpj changed the title Pin versions of plugins Pin versions of libraries used by plugins May 4, 2022
@michaelpj
Copy link
Collaborator

michaelpj commented May 4, 2022

I think pinning precise versions of underlying tools is a good idea. It may make it harder to get build plans for all GHCs, though...

@mitchellwrosen
Copy link
Author

@michaelpj Thanks, that's what I started to do, but then I got a little bit stuck and scared due to the requirement to use a different version of HLS for different versions of GHC, all tied together with the haskell-language-server-wrapper.

I'm happy to build everything from source, too, but I could use a bit of guidance :)

I see that after some usage of ghcup to install ghc and hls, I've accumulate these variants:

haskell-language-server-8.10.7
haskell-language-server-8.10.7~1.7.0.0
haskell-language-server-8.6.5
haskell-language-server-8.6.5~1.7.0.0
haskell-language-server-8.8.4
haskell-language-server-8.8.4~1.7.0.0
haskell-language-server-9.0.2
haskell-language-server-9.0.2~1.7.0.0
haskell-language-server-9.2.1
haskell-language-server-9.2.1~1.7.0.0
haskell-language-server-9.2.2
haskell-language-server-9.2.2~1.7.0.0
haskell-language-server-wrapper
haskell-language-server-wrapper-1.7.0.0

Were I to ditch ghcup to install hls, and instead build from source in order to constrain the version of ormolu it depends on, do you happen to know all of the steps required to end up with the right binaries with the right names? Perhaps there is a shell script somewhere in this repo I could run?

Thanks.

@michaelpj
Copy link
Collaborator

I think ghcup can compile HLS from source with additions to the project file (we use Nix at work, but it depends a lot on your setup).

@pepeiborra
Copy link
Collaborator

If there was a freeze file checked into this repo, that would effectively achieve the same result.

Just to clarify - by "you" do you mean "you, Mitchell", or "one"?

I mean you Mitchell. We cannot use a single freeze file since we want to support a range of ghc versions, and libraries like ghc-lib, ghc-exactprint or retrie are versioned following ghc versions.

We do maintain a selection of stack files that provide deterministic builds, and you can use cabal freeze to "roll your own". But I don't think that we should take it any further than that: deterministic builds are hard and expensive to maintain.

@mitchellwrosen
Copy link
Author

I mean you Mitchell. We cannot use a single freeze file since we want to support a range of ghc versions, and libraries like ghc-lib, ghc-exactprint or retrie are versioned following ghc versions.

We do maintain a selection of stack files that provide deterministic builds, and you can use cabal freeze to "roll your own". But I don't think that we should take it any further than that: deterministic builds are hard and expensive to maintain.

I admit I don't fully grasp what is expensive or hard to maintain about deterministic builds - but I take your word for it. FWIW, in case this changes anything, I am only imagining a frozen set of dependencies for the released version(s) of HLS. That way, everyone using HLS version 1.7.0.0, for example, need look no further than that version string to know whether their software has the same set of transitive dependencies as another user's, no matter if they built from source, or acquired hls from ghcup, or nix, or however else one might go about installing it.

But if that doesn't work, then (just reiterating my previous comment) I think it would be valuable to have some documentation somewhere about how intrepid users might go about getting a working HLS "suite". Because as I mentioned, it's simple enough to to just cabal build this package with a --constraint flag or two, but I'm a bit lost when it comes to building HLS once per GHC version, and getting everything aligned correctly for use via the haskell-language-server-wrapper executable.

@pepeiborra
Copy link
Collaborator

We already produce cabal.project.freeze files in CI, although they are only ephemeral. It would be trivial to output them as CI artifacts, and then they can be bundled with HLS binary releases or similar.

If this is something that would be useful to you, by all means send a PR! This is where CI calls cabal freeze:

- name: Form the package list ('cabal.project.freeze')
run: |
rm cabal.project.freeze || \
cabal v2-freeze && \
echo "" && \
echo 'Output:' && \
echo "" && \
cat 'cabal.project.freeze'

@wz1000 wz1000 added CI Continuous integration level: easy The issue is suited for beginners documentation and removed status: needs triage labels Sep 7, 2022
@georgefst
Copy link
Collaborator

We already produce cabal.project.freeze files in CI, although they are only ephemeral. It would be trivial to output them as CI artifacts, and then they can be bundled with HLS binary releases or similar.

I'm currently trying to debug a plugin regression, and this would have been very useful to have!

@michaelpj
Copy link
Collaborator

For most of the plugins that depend on external tools, you can now see which version using haskell-language-server --list-plugins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI Continuous integration documentation level: easy The issue is suited for beginners type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants