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

Ability to promote freeze files to lock files #10784

Open
LaurentRDC opened this issue Feb 8, 2025 · 7 comments
Open

Ability to promote freeze files to lock files #10784

LaurentRDC opened this issue Feb 8, 2025 · 7 comments

Comments

@LaurentRDC
Copy link

Describe the feature request

Currently, cabal freeze creates a file full of build constraints. These build constraints must be respected, but dependencies outside of these constraints can also be built (see example below).

Example

Consider the following cabal file:

executable myexe
  build-depends:  base, containers

Executing cabal freeze would generate a file like so:

active-repositories: hackage.haskell.org:merge
constraints: any.base ==4.20.0.0,
             any.containers ==0.7,
index-state: ...

If I go ahead and modify my cabal file, e.g. to add a dependency on text:

executable myexe
  build-depends:  base, containers, text

My project will still build, even if text isn't part of cabal.project.freeze.

My requested feature is to have a lock file, which would be almost identical to a freeze file, with the additional requirement that no dependencies without constraints may be used. In practice, this could be something like having a flag in cabal.project.freeze to specify whether constraints are exhaustive or not, instead of a whole new mechanism that parallels freeze files.

I am happy to work on implementing this feature!

Additional context

At work, we're currently using stack and its lockfile support to restrict dependencies to approved packages. We work in a tighly regulated industry, where all dependencies must be audited.

Before switching to use cabal, we want to have assurances that cabal will not pull in additional dependencies.

@LaurentRDC LaurentRDC changed the title Ability to create lock files Ability to promote freeze files to lock files Feb 8, 2025
@grayjay
Copy link
Collaborator

grayjay commented Feb 8, 2025

One option is to use the flag --reject-unconstrained-dependencies. Maybe freeze files could be modified to specify whether they should always enable that flag.

@LaurentRDC
Copy link
Author

Ah, very nice!
Indeed, it would be nice to have this flag optionally in the freeze file itself, making it effectively a self-contained lockfile

@LaurentRDC
Copy link
Author

Worth noting at this time that you can activate this flag using cabal configure / in the project file:

cabal configure --reject-unconstrained-dependencies=all

so we're very close!

@LaurentRDC
Copy link
Author

See here for a discussion

@hasufell
Copy link
Member

I suggest to have a clear understanding of what:

  • a freeze file is
  • "locking" mechanism is supposed to achieve

I think what the proposer really wants is to not do any dependency resolution whatsoever. Cabal freeze files are not a proper mechanism for that, imo.

To me it seems, what is desired here is re-using a cabal build plan. The build plan already contains the exact description of the build + hashes. However, it is fixed to a particular platform (os and arch). This is also closer to what stack does... stack does not do resolution.

However, I do remember that even with a cabal build plan, there is some non-determinism. I forgot what it was, I think @andreabedini knows (and I don't mean system libs).

@andreabedini
Copy link
Collaborator

@LaurentRDC thank you for opening this and for giving it a shot in #8605. It's very appreciated!

I believe the critical point here is to separate further the planning and the building phase, allowing cabal-install to build an existing plan rather than re-executing the solver.

I think this is very important for UX because I see solving and building as separate concerns which require different handling and different user interaction.

Doing the above would basically give you a real "lockfile". Mind that there are questions around system dependencies (e.g. pkg-config, os, arch and impl in cabal files).I do not have an answer for those but my gut feeling is that a pragmatic approach is possible, as long as the UX supports it.

I did have a go (or three) at devoiding ProjectBuilding of any guessing but I always got stuck refactoring SetupWrapper.

@gbaz
Copy link
Collaborator

gbaz commented Feb 10, 2025

As I commented on the discourse discussion, I don't think that any lockfile-alone solution really gives the full all-dependencies-audited guarantees one wants with tight compliance. The real solution there is to use a repo of only audited things. At work we use nix for this. But one can also do it directly with cabal, with a local no-index repo: https://cabal.readthedocs.io/en/3.6/installing-packages.html#local-no-index-repositories

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants