FromCabal.Name: stop resolving executables from pkgs.nix to nix attr#683
Merged
sternenseemann merged 1 commit intomasterfrom Oct 31, 2025
Merged
FromCabal.Name: stop resolving executables from pkgs.nix to nix attr#683sternenseemann merged 1 commit intomasterfrom
sternenseemann merged 1 commit intomasterfrom
Conversation
We use resolveInHackageThenNixpkgs for build-tools and build-tool-depends. Since a "nix" package has been uploaded to Hackage on 2025-10-16, this has started to resolve to a Hackage packages which isn't the intent in any of these cases. The fundamental problem here is that resolveInHackageThenNixpkgs is correct because of the strange semantics of build-tool-depends and build-tools. _Both_ are intended for “A list of Haskell programs needed to build this component”. build-tool-depends creates a dependency on an executable component of another (Cabal) package. However, in the case of build-tools Cabal usually won't try to pull in third party dependencies. It uses other executables in the same package or tries looking the executable in a very small [table][] it knows about. Otherwise, the user is expected to make sure that the executable is in PATH. This allows for abusing this mechanism to depend on non-Haskell executables, as done in e.g. nix-paths. If Cabal doesn't know the executable, it just looks at PATH without enforcing that the program has been built and installed by Cabal. Consequently, cabal2nix should try its best guessing the package the desired executable comes from or at least generate an attribute that allows users to pass the appropriate package in. Given that the field is intended for “Haskell programs”, using resolveInHackageThenNixpkgs is the best option. Since this field is deprecated and largely ignored by Cabal, there may be temptation (even on my part) to interpret build-tools as a sort of declaration for dependencies on non-Haskell executables first and foremost. However, overall this is probably not a good idea because, at best, it creates an ad hoc feature that is only supported by cabal2nix, potentially worsening the experience for everyone else. One thing we could do, is change buildToolNixName in a way that it can explicitly return whether to look for the package in the Hackage or Nixpkgs scope first. The slight problem with this is, of course, that we can't know for all eternity that no “Haskell program” with a clashing name exists. [table]: https://cabal.readthedocs.io/en/stable/cabal-package-description-file.html#buildtoolsmap
wolfgangwalther
approved these changes
Oct 26, 2025
Contributor
wolfgangwalther
left a comment
There was a problem hiding this comment.
I don't claim to understand all the possible implications etc., but your reasoning reads sound.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
We use resolveInHackageThenNixpkgs for build-tools and build-tool-depends. Since a "nix" package has been uploaded to Hackage on 2025-10-16, this has started to resolve to a Hackage packages which isn't the intent in any of these cases.
The fundamental problem here is that resolveInHackageThenNixpkgs is correct because of the strange semantics of build-tool-depends and build-tools. Both are intended for “A list of Haskell programs needed to build this component”.
build-tool-depends creates a dependency on an executable component of another (Cabal) package.
However, in the case of build-tools Cabal usually won't try to pull in third party dependencies. It uses other executables in the same package or tries looking the executable in a very small table it knows about. Otherwise, the user is expected to make sure that the executable is in PATH.
This allows for abusing this mechanism to depend on non-Haskell executables, as done in e.g. nix-paths. If Cabal doesn't know the executable, it just looks at PATH without enforcing that the program has been built and installed by Cabal.
Consequently, cabal2nix should try its best guessing the package the desired executable comes from or at least generate an attribute that allows users to pass the appropriate package in.
Given that the field is intended for “Haskell programs”, using resolveInHackageThenNixpkgs is the best option. Since this field is deprecated and largely ignored by Cabal, there may be temptation (even on my part) to interpret build-tools as a sort of declaration for dependencies on non-Haskell executables first and foremost. However, overall this is probably not a good idea because, at best, it creates an ad hoc feature that is only supported by cabal2nix, potentially worsening the experience for everyone else.
One thing we could do, is change buildToolNixName in a way that it can explicitly return whether to look for the package in the Hackage or Nixpkgs scope first. The slight problem with this is, of course, that we can't know for all eternity that no “Haskell program” with a clashing name exists.
The only package on Hackage affected by this is
nix-pathswhich got broken by the upload ofnix.