-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
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
Haskell bash completion #42657
Haskell bash completion #42657
Conversation
d2441b6
to
0c08cd8
Compare
0c08cd8
to
ce44c8b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool stuff!
What do you think of making this a standard procedure for all packages? So, adding optparse-applicative
to the dependencies should automatically set up a postInstall hook that tries to run --bash-completion-script
on all binaries, install the result on success, or fail silently (in case it's not supported).
Pinging some Haskell people @peti @shlevy @domenkozar @Profpatsch
@infinisil, others, I have thought about trying all executables but was a bit wary of the side effects. A package might include both a command line tool and an executable that fails in the sandbox, or takes a very long time to complete. I have already spent too much time debugging silent failures. These kinds of failures are probably rare, so I'd rather require an override to selectively disable this feature, rather than give a one-line cue in an already verbose build log. To make an opt-out design work without too nasty surprise, it should involve at least
An intermediate possibility is to require opt-in but not require to list the command line executables. That should give an opportunity to test the logic above that may become the opt-out solution. |
This is just for getting the output of |
@infinisil I agree that completion is secondary, but my concern is about bitrot. If we're going to fail silently we should at least test some high profile haskell packages. Five minute timeout is for a builder with high load to recover. It's only 2.5 orders of magnitude more ;) Do we have a place for (small) integration tests in nixpkgs nowadays? I think I can live with soft failure in this case if we have warnings in the log and some test cases to prevent bitrot. |
I'd love to see some thought put into a more general notion of how packages interact with installation environments, but for now some kind of post install hook seems great to me |
@roberth By bitrot you mean the completion scripts potentially failing for more packages over time without anybody noticing? Does that really happen? I can't think of anything that could go wrong with such a simple post build hook. |
@infinisil That's what I mean. I don't expect anything in particular to go wrong either. I just want to set things up so that when they do go wrong, they get noticed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the PR, thank you very much! I have some bike-shedding suggestions with regard to the name of that combinator, but I'm hugely in favor of having this function available in Nixpkgs.
* command: name of an executable | ||
* pkg: Haskell package that build the executable | ||
*/ | ||
appendCompletion = command: pkg: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that generateCompletion
is a more descriptive name than appendCompletion
. Also, there might be more than one way to generate those files depending on which option parsing library is used, therefore it might be a good idea to put the optparse-applicative
in there somehow, i.e. generateOptparseApplicativeCompletion
.
appendCompletion = command: pkg: | ||
overrideCabal pkg (old: { | ||
postInstall = old.postInstall or "" + '' | ||
echo "installing bash completion script for ${command}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we'd also want completion files for zsh
and fish
? optparse-applicative
can generate those as well.
It's interesting to note that the generated completion files are totally generic, i.e. they contain no code that's specific to the executable in questions other than its name and full path:
So arguably we could generate those files without actually running the executable, which is a trait the cross-compilation people would surely appreciate. The downside is, of course, that we expose ourselves to potential incompatibilities that might occur across different versions of |
@@ -658,7 +658,7 @@ self: super: { | |||
})); | |||
|
|||
# Need newer versions of their dependencies than the ones we have in LTS-11.x. | |||
cabal2nix = super.cabal2nix.overrideScope (self: super: { hpack = addTestToolDepend (self.hpack_0_28_2) self.hspec-discover; hackage-db = self.hackage-db_2_0_1; }); | |||
cabal2nix = appendCompletions ["cabal2nix"] (super.cabal2nix.overrideScope (self: super: { hpack = addTestToolDepend (self.hpack_0_28_2) self.hspec-discover; hackage-db = self.hackage-db_2_0_1; })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note that cabal2nix
(and some other tools) have similar overrides already in pkgs/top-level/all-packages.nix
and elsewhere, so we have to make sure those are removed as part of this PR:
$ grep -R -- --bash-completion-script pkgs
pkgs/development/haskell-modules/hackage-packages.nix: $exe --bash-completion-script $exe >$out/share/bash-completion/completions/stack
pkgs/top-level/all-packages.nix: $exe --bash-completion-script $exe >$out/share/bash-completion/completions/${drv.pname}
@peti, interesting observation for cross compilation. I should add though that running This is not a concern for the current state of the PR, but it is for the opt-out approach. I think opt-out is feasible and I want to give it a try soon. |
I am not particularly fond of the opt-out approach because it seems like
a bad idea to run arbitrary executables as part of the build without
having any clue about what they are doing.
|
@peti It's all sandboxed anyways though, what bad could happen? If we can't find some serious problem/risk with the opt-out approach, this would be a huge usability improvement, especially since so many packages are using optparse-applicative. |
I understand peti’s concerns, it will make debugging harder. It also has a taste of an inverse |
Although I think a well-implemented opt-out approach is valuable, it will take more time than I can realistically expect to spend on it short/mid-term. I will limit the scope of this PR to opt-in. |
The optparse-applicative library provides a uniform method of adding completions to haskell programs. These functions capture that. Other shells than bash are supported by the library, so if anyone is interested, they could add it to the appendCompletion function.
ce44c8b
to
75788c9
Compare
to do
fishFor fish I could use some help. It doesn't pick up the completion from cross compilationThe fish and zsh completions are 'adapters' that use optparse's |
Ping? |
Don't wait for me if you want to have this in 18.09 :( |
Am I too diligent? #49477 |
This adds the remaining parts of NixOS#42657 on top of NixOS#49477, renames the function to a better name, and improves the docs
Motivation for this change
The
optparse-applicative
library provides a uniform method of adding completions to haskell programs. This introduces two helper functions inhaskell.lib
that capture that.This PR also adds completion to a small number of Haskell commands that are built with this library.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)