Is every hackage package buildable?

Of course I had a go at this using --allow-boot-library-install

❯ cabal repl -w ghc-9.4 -b ghc --constraint 'ghc == 9.8.1' --allow-boot-library-install
Resolving dependencies...
Error: cabal: Could not resolve dependencies:
[__0] trying: fake-package-0 (user goal)
[__1] next goal: ghc (dependency of fake-package)
[__1] rejecting: ghc-9.4.7/installed-9.4.7 (constraint from command line flag
requires ==9.8.1)
[__1] trying: ghc-9.8.1
[__2] next goal: ghci (dependency of ghc +/-static-libzstd +/-with-libzstd)
[__2] rejecting: ghci-9.4.7/installed-9.4.7, ghci-8.10.2, ghci-8.10.1,
ghci-8.8.3, ghci-8.8.1, ghci-8.6.5, ghci-8.6.4, ghci-8.6.1, ghci-8.4.4,
ghci-8.4.3, ghci-8.4.2, ghci-8.4.1, ghci-8.2.2, ghci-8.2.1, ghci-8.0.2,
ghci-8.0.1 (conflict: ghc +/-static-libzstd +/-with-libzstd => ghci==9.8.1)
[__2] fail (backjumping, conflict set: ghc, ghci)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: ghc, ghci, fake-package

The failure is more mundane than I expected. The package ghc depends on ghci and ghci has not been uploaded to hackage since version 8.10.2. So there is just no source to build :upside_down_face:

1 Like

Isn’t haskellPackages all pinned to a single version? And a single version of ghc. That’s the equivalent of a global stackage, which ofc won’t all build.

1 Like

Indeed, I am a frequent dontCheck user :slightly_smiling_face:.

What would it take to optionally inform Hackage how to build a package, either during or after the upload? Would a cabal.project.freeze file be sufficient?

The package metadata (aka the cabal-file) is what makes the package buildable (in theory, of course system dependencies, compiler versions, etc can affect this).
The good news is that Hackage/cabal-install support updating the metadata without a new release.

The package metadata (aka the cabal-file) is what makes the package buildable (in theory, of course system dependencies, compiler versions, etc can affect this).

My question is how to provide evidence to Hackage that the package is buildable in practice.

A package should not only be buildable with a given freeze file. It should be buildable regardless, because the constraints should be such that the solver can actually resolve them and build the package. The evidence is then, as andrea said, the cabal file itself, and the verification is the builder successfully building the package based on that file.

1 Like

That’s a lot of shoulds.

OP is asking (among other things, in my understanding) how to find out if a published package was ever buildable and how. Since my attempts at pithy questions seem to be misunderstood, allow me to explain at some length.

Having a constructive proof of build would be helpful for several reasons:

  • For people trying to revive an abandoned package, the best way to start is usually trying to somehow build the package in working condition. The package dependency bounds may be too wide and leading to compiler failures, or too narrow for recent versions of GHC. Maybe the package builds only with some special setting overrides in its cabal.project file, which is not a part of a Hackage upload.
  • For people choosing among N libraries that provide some functionality they need, having a “known to build” badge would be a helpful piece of criteria.
  • If the matrix builder were started up again, it would be helpful for its results to be shared at each package page on Hackage. Every successful build is a proof of build, but then why not record exactly what it took?
  • Once we have an exact proof of build, we can assume there’s never any need to repeat it. In other words, we can use it as a cache and reduce the resource requirements for the next Hackage matrix run.
  • Of course a failure proof can be valuable for similar reasons, caching etc, plus it would be a useful artifact for bug reporting.

Ideally, we could one day have a cabal upload-build-info that anybody could use to upload non-fakeable proof of a package’s build success or failure on their local machine to Hackage. However, the first step would be to decide what form this proof would take. Thus my question above: what would be the minimal data set required to reliably replicate the build environment on another machine? Of course the problem could be simplified if we only had to deal with Nix or Stack, but what if we can assume only that cabal build is used?

2 Likes

Well, I think the problem as you put it is too broad to be solvable in general.

Thus my question above: what would be the minimal data set required to reliably replicate the build environment on another machine?

FWIW Nix offers a practical answer to this question. Other common solutions in this space range from containers to virtual machines.

The hackage server allows upload of build reports that record the version of ghc used, the os used, and the versions of all dependencies used: Hackage: Build #1 for frisby-0.2.5

These are currently generated and uploaded by the docbuilder, but package maintainers can upload them themselves as well. There was an intention back when this was introduced that end-users could also submit anonymous build reports (essentially the upload-build-info command you suggest), but this was never fully fleshed out into a deployed implementation, because of a lot of open questions on how exactly to do this best and most usefully. (As well as a lack of hands to implement).

This is of course not “formally verified” or certified with a signature or the like, but it certainly does qualify as evidence of the sort you ask for.

In fact, the page itself of the package has exactly the known-to-build badge requested! See e.g. freer-par-monad: Freer par monad

Along with the known-to-build badge, we have a badge if the tests run successfully, and what percent code coverage the tests give.

4 Likes

It does, thank you! That’s gone much further than I expected. One relatively easy step to take next would be to add some search filters with these properties to the Hackage search page. It tried to enter the search terms (Build:InstallOk) json manually but it doesn’t filter for buildable packages only.

1 Like