haskell / ghcup-hs

https://www.haskell.org/ghcup/
GNU Lesser General Public License v3.0
287 stars 88 forks source link

Configure cabal bash autocompletion after installation #360

Open hasufell opened 2 years ago

hasufell commented 2 years ago

In GitLab by @chshersh on Apr 23, 2022, 05:58

I wonder if it's possible to configure cabal autocompletion after installing cabal with ghcup.

I found this bash autocompletion script in the repository:

It's okay if this is not in scope for ghcup but I thought it would be nice to have an even better configured cabal setup!

hasufell commented 2 years ago

In GitLab by @maerwald on Apr 23, 2022, 14:32

We had a similar discussion about GHC completion here: https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/288

My point is: it can be done, but only if it's part of the official cabal bindist, because ghcup doesn't support multiple archives per tool, since that would complicate the code.

hasufell commented 2 years ago

In GitLab by @chshersh on Apr 23, 2022, 17:24

I've created the corresponding issue in cabal to track this feature:

hseg commented 9 months ago

Ping on this? It's a nice-to-have whose absence I'd rather not patch around. (At the moment, I've downloaded a copy of the cabal bash completion to $XDG_DATA_HOME/bash-completion/completions/, but I'd rather those files be upstreamed as much as possible)

hasufell commented 9 months ago

@hseg I don't see any bash completions in the existing release tarballs. That's where we want to get them from.

hseg commented 9 months ago

On Sat, Jan 20, 2024 at 06:24:12PM -0800, Julian Ospald wrote:

@hseg I don't see any bash completions in the existing release tarballs. That's where we want to get them from.

Right, could've been clearer -- in contrast to #298, which seems to have been resolved upstream (despite the completions still not appearing, see there), here upstream appears to be waiting on clarification from ghcup devs on what exactly is needed for the completions to indeed install under ghcup's framework.

hasufell commented 9 months ago

I don't really know. GHCup does not install into random directories under HOME. And there are a hundred different ways to configure and install bash completions. How do you propose this works reliably?

The only thing I can imagine is that ghcup puts them under ~/.ghcup/bash_completion.d and then lets the user figure out how to use that.

hseg commented 9 months ago

On Sun, Jan 21, 2024 at 04:20:03AM -0800, Julian Ospald wrote:

I don't really know. GHCup does not install into random directories under HOME. And there are a hundred different ways to configure and install bash completions. How do you propose this works reliably?

The only thing I can imagine is that ghcup puts them under ~/.ghcup/bash_completion.d and then lets the user figure out how to use that.

That looks good enough -- judging by the last question on https://github.com/scop/bash-completion/, users would then need to add the directory to BASH_COMPLETION_USER_DIR.

Although, depending on the logic there, it might be able to pick up completions installed to ~/.ghcup/ghc/$ver/share/bash-completion/completions.

In considering this, and noting the existence of the symlink ~/.ghcup/share, I'm left wondering if perhaps an alternative design could be for ghcup to maintain ~/.ghcup/{bin,lib,share} that are unions of all the trees managed by ghcup, and to have users add those directories to the appropriate environment variables (PATH, XDG_DATA_DIRS, etc)

hasufell commented 9 months ago

I'm left wondering if perhaps an alternative design could be for ghcup to maintain ~/.ghcup/{bin,lib,share} that are unions of all the trees managed by ghcup, and to have users add those directories to the appropriate environment variables (PATH, XDG_DATA_DIRS, etc)

I don't really understand this part.

hseg commented 9 months ago

On Sun, Jan 21, 2024 at 04:51:46AM -0800, Julian Ospald wrote:

I'm left wondering if perhaps an alternative design could be for ghcup to maintain ~/.ghcup/{bin,lib,share} that are unions of all the trees managed by ghcup, and to have users add those directories to the appropriate environment variables (PATH, XDG_DATA_DIRS, etc)

I don't really understand this part.

(This is very speculative, and might not be worth pursuing -- indeed, the more I think about it the more it appears to be a deep overhaul of its own that might not be justified)

The idea is to keep all the installations under ~/.ghcup (perhaps making an exception for those symlinks installed using ghcup set), and to gather whatever files would be installed elsewhere in an equivalent under ~/.ghcup. So:

In practice, this would mostly just mean that instead of installing all the $tool-$ver symlinks to XDG_BIN_HOME, these'd land under ~/.ghcup/bin.

Though now I've spelled it out, the benefits (other than further motivating installing completions under ~/.ghcup/share) seem negligible.

hasufell commented 9 months ago

I've very low appetite to change the directory/file layout, which:

And in general: GHCup's approach is to consolidate the installation of a version under a single directory. It does not follow a stringent FHS hierarchy. That is on purpose. It's a "home installer". XDG is broken.

hseg commented 9 months ago

On Sun, Jan 21, 2024 at 07:18:57PM -0800, Julian Ospald wrote:

I've very low appetite to change the directory/file layout, which:

  • will be a large breaking change for all sorts of tools and scripts that assume specific locations from ghcup
  • requires a migration strategy for existing installations and potentially supporting both formats
  • requires much stronger arguments, one of which is https://github.com/haskell/ghcup-hs/issues/375

And in general: GHCup's approach is to consolidate the installation of a version under a single directory. It does not follow a stringent FHS hierarchy. That is on purpose. It's a "home installer". XDG is broken.

Right, hence my qualifiers on this approach -- "very speculative", "might not be worth pursuing", "is a deep overhaul that might not be justified". In re the last points, I think our understanding is close enough that I don't think I can usefully express the slight differences I do see.

Hence, returning to the sane suggestions, I'd suggest completions be installed to ~/.ghcup/$tool/$ver/share/bash-completion-completions or to ~/.ghcup/share/bash-completion-completions. IIUC, the former should be picked up by bash-completion automatically -- otherwise, the latter + a recommendation to add it to BASH_COMPLETION_USER_DIR should always work.

Incidentally, in case we indeed go with installing completions under ~/.ghcup/$tool/$ver/, it might strengthen the case for #375 -- after all, in that case the cabal and stack installations would consist of more than just the binaries.

I don't know what the directories zsh and fish expect, but I imagine the situation for them is similar.

hasufell commented 9 months ago

The problem is that ~/.ghcup/$tool is not consistent, see https://github.com/haskell/ghcup-hs/issues/375 as mentioned earlier. There's no ~/.ghcup/cabal directory. That was a design mistake, but is hard to revert.

hseg commented 9 months ago

On Mon, Jan 22, 2024 at 12:50:27AM -0800, Julian Ospald wrote:

The problem is that ~/.ghcup/$tool is not consistent, see https://github.com/haskell/ghcup-hs/issues/375 as mentioned earlier. There's no ~/.ghcup/cabal directory. That was a design mistake, but is hard to revert.

OK, so a quick test shows installing completions to ~/.ghcup/$tool/$ver/share/bash-completion/completions/$tool indeed works.

Four possibilities in re cabal/stack which don't have their own ~/.ghcup/$tool/ directories:

hasufell commented 9 months ago

There's a lot of things floating around and your text is very hard to read (totally unformatted).

We won't use any XDG variables ever, unless the user has enabled GHCUP_USE_XDG.

a quick test shows installing completions to ~/.ghcup/$tool/$ver/share/bash-completion/completions/$tool indeed works

What does this mean "works"? Can you be more specific?

As for a migration process, a possible solution is to teach ghcup upgrade how to store the current toolchain state in some cache, then uninstall everything, upgrade, and restore everything from that cache

Yes, I thought about that, but you're aware this would require 2 upgrades to work? The first upgrade will make sure the GHCup binary has the migration logic, but it won't be triggered until the next release. What if a user skips the middle release? So we're stuck with supporting both variants anyway.

If the store/restore verbs were added to the commands ghcup knows about, packagers could then tell users to manually run these commands if using a packaged ghcup

That's a huge design space, in fact.

It's also fairly disruptive.

Another option is to simply do the migration logic silently at startup. I'm actually in favor of that one. But it's technically also "bad form". I'm not able to foresee all the issues this could cause (e.g. what if the migration logic is constantly triggered due to a bug).

hseg commented 9 months ago

On Wed, Jan 24, 2024 at 04:32:50AM +0000, Julian Ospald wrote:

There's a lot of things floating around and your text is very hard to read (totally unformatted).

Unfortunately, Github doesn't render formatting from emails.

We won't use any XDG variables ever, unless the user has enabled GHCUP_USE_XDG.

Fair enough -- that kills the second of my options. I presume this ban on XDG does not extend to documentation, though? In particular, it would be within scope to add a paragraph saying something like:

ghcup will install bash completions for the tools you install to $(ghcup whereis basedir)/bash-completion/completions/ If you want bash-completion to pick up these completions, one way mechanism they support is adding this directory to XDG_DATA_DIRS

Otherwise, the only other alternatives I see are:

a quick test shows installing completions to ~/.ghcup/$tool/$ver/share/bash-completion/completions/$tool indeed works

What does this mean "works"? Can you be more specific?

As in, bash-completion looks for completions for $bin/$cmd at $bin/../share/bash-completion/completions/$cmd. Notably, this lookup sees through symlinks. Therefore, with the standard XDG ghcup setup where one has

bash-completion will pick up a completion installed to ~/.ghcup/ghc/$ver/share/bash-completion/completions/ghc (note: even though ~/.ghcup/ghc/$ver/bin/ghc is not itself in PATH!)

As for a migration process, a possible solution is to teach ghcup upgrade how to store the current toolchain state in some cache, then uninstall everything, upgrade, and restore everything from that cache

Yes, I thought about that, but you're aware this would require 2 upgrades to work? The first upgrade will make sure the GHCup binary has the migration logic, but it won't be triggered until the next release. What if a user skips the middle release? So we're stuck with supporting both variants anyway.

Another option is to simply do the migration logic silently at startup. I'm actually in favor of that one. But it's technically also "bad form". I'm not able to foresee all the issues this could cause (e.g. what if the migration logic is constantly triggered due to a bug).

If I understood your design correctly, it doesn't differ much from mine here.

An alternative possibility is to have ghcup upgrade contain this migration logic, and to add a ghcup test ghcup that checks if the filesystem layout matches expectations. Then a piece of troubleshooting advice would be to make sure ghcup test ghcup passes, and it would suggest running ghcup upgrade if it noticed an old filesystem layout.

hseg commented 8 months ago

On Sat, Jan 20, 2024 at 06:24:12PM -0800, Julian Ospald wrote: @hseg I don't see any bash completions in the existing release tarballs. That's where we want to get them from. Right, could've been clearer -- in contrast to #298, which seems to have been resolved upstream (despite the completions still not appearing, see there), here upstream appears to be waiting on clarification from ghcup devs on what exactly is needed for the completions to indeed install under ghcup's framework.

Since I went through #298 again, am pinging here as well. Does ghcup just copy the binary, or does it run some Makefile like it does for ghc? If it's the former, then ghcup also needs changes so as to pick up the completion files we're asking the cabal folks to add in https://github.com/haskell/cabal/issues/8107. Either way, they need to know where to place the files.

As for the location to install the completions, either we wait for #375, or we could install them to ~/.ghcup/share/bash-completion/completions/ ($XDG_DATA_HOME/ghcup/share/bash-completion/completions/ if using XDG dirs) and direct users to add them to their BASH_COMPLETION_USER_DIR (much as we direct them to add ~/.local/bin to their PATH).

hasufell commented 8 months ago

Does ghcup just copy the binary, or does it run some Makefile like it does for ghc

cabal bindists don't ship with a Makefile.

Either way, they need to know where to place the files.

I have no idea. The location should be configurable anyway.

As for the location to install the completions

Yeah, this needs some thought. I'm not too keen to make a quice decision. Because decisions about locations are hard to impossible to revert.

hseg commented 8 months ago

Does ghcup just copy the binary, or does it run some Makefile like it does for ghc

cabal bindists don't ship with a Makefile.

Right, was floating this as an option of what to ask of them, since you've previously made it clear you don't want to have ghcup know too much about tool internals. Otherwise, the ask is just "Have the bindist be a tarball of binary+license+completion+manual?", and having us install each in the correct location manually.

... on further reflection -- isn't this what ghcup is evolving into? A package manager for the half-dozen haskell toolchain packages? In which case, it seems we either need to specify a contract of expectations in re the tool bindists, or repackage them ourselves/hardcode the repackaging into ghcup itself.

Perhaps a useful thought-testcase here is -- say I wanted to add support for hugs to ghcup. How would I go about it? What is ghcup looking for from the tarball I point it to, and what does it do with it?

Either way, they need to know where to place the files.

I have no idea. The location should be configurable anyway.

Actually, there's a thought in re the versioning problem -- perhaps we should have a ~/.ghcup/ghcup.conf (= $XDG_CONFIG_DIR/ghcup/ghcup.conf) which configures eg tool paths? It could be versioned, and we could then specify that in the absence of a config file we default to current behaviour (aka version 0), and that we warn when the tool version and the config version are out of sync.

As for the location to install the completions

Yeah, this needs some thought. I'm not too keen to make a quice decision. Because decisions about locations are hard to impossible to revert.

In this case, the stakes are a bit lower -- at worst, we'll have the wart of having to tell users to explicitly add the completion director(y/ies) to their shell config/an environment variable, no worse than the initial setup of having to set PATH -- see the discussion on search locations in https://github.com/scop/bash-completion/ https://github.com/zsh-users/zsh-completions https://fishshell.com/docs/current/completions.html