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

cabal-install: Clarify the semantics of package-db flag #9683

Merged
merged 1 commit into from
Feb 25, 2024

Conversation

mpickering
Copy link
Collaborator

In this PR we make the --package-db flag apply only to the default immutable initial package stack rather than also applying to the store package database.

There are two special package databases which cabal install knows about and treats specially.

  • The store directory, a global cache of installed packages where cabal builds and installs packages into.
  • The inplace directory, a local build folder for packages, where cabal builds local packages in.

It is very important that cabal registers packages it builds into one of these two locations as there are many assumptions that packages will end up here.

With the current design of the --package-db flag, you are apparently allowed to override the store location which should have the effect of making the last package database in the package stack the "store" directory. Perhaps this works out in theory but practically this behaviour was broken and things were always registered into the store directory that cabal knew about. (The assertion in ProjectBuilding.UnpackedPackage was failing (see added test)).

With --package-db not being able to modify the location of the store directory then the interaction of --package-db, --store-dir and --dist-dir flags become easy to understand.

  • --package-db modify the initial package database stack, these package database will not be mutated by cabal and provide the initial package environment which is used by cabal.
  • --store-dir modify the location of the store directory
  • --dist-dir modify the location of the dist directory (and hence inplace package database)

Treating the flags in this way also fix an assertion failure when building packages.

Please read Github PR Conventions and then fill in one of these two templates.


Template Α: This PR modifies cabal behaviour

Include the following checklist in your PR:

  • Patches conform to the coding conventions.
  • Any changes that could be relevant to users have been recorded in the changelog.
  • The documentation has been updated, if necessary.
  • Manual QA notes have been included.
  • Tests have been added. (Ask for help if you don’t know how to write them! Ask for an exemption if tests are too complex for too little coverage!)

Template Β: This PR does not modify cabal behaviour (documentation, tests, refactoring, etc.)

Include the following checklist in your PR:

library
import: warnings
exposed-modules: MyLib
build-depends: base ^>=4.18.0.0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this restrict the ghc versions this test can be run with?

@fgaz fgaz linked an issue Feb 2, 2024 that may be closed by this pull request
@mpickering mpickering force-pushed the wip/package-db-fix branch 2 times, most recently from bcdee26 to f1e14f7 Compare February 2, 2024 10:12
Copy link
Collaborator

@andreabedini andreabedini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that --package-db should not affect the store but let's find a cleaner way to implement this.

Comment on lines 447 to 448
cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir
cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir projectConfigPackageDBs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should raise eyebrows. How come the CABAL_DIR layout now depends on project level configuration?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the initial package database stack depends on the package-db option, which is specified at a project level.

This seems completely natural to me, and changing the implementation like this caught the fact that --package-db flag was not honoured by the install command. What is your proposed alternative?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The layout of CABAL_DIR does not depend on any project configuration. What happens here is that CabalDirLayout contains (through StoreDirLayout)

storePackageDBStack :: Compiler -> PackageDBStack
storePackageDBStack compiler = [GlobalPackageDB, storePackageDB compiler]

You want to insert project packagedbs inside that stack and you cannot do it. IMHO the right solution is either

  1. Change that function to take a list of packagedb (just like it takes a compiler):
storePackageDBStack :: Compiler -> [PackageDB] -> PackageDBStack
storePackageDBStack compiler packagedbs = GlobalPackageDB : packagedbs ++ [storePackageDB compiler]

(modulo a Just, I think we should only allow "real" packagedbs rather than "maybe encoded packagedb commands")

or

  1. Remove that function entirely and rely on storePackageDB :: Compiler -> PackageDB instead. The accessor storePackageDBStack does not really save any code and you just have proven that it was hiding an important decision (the order).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good idea to change the function to take an extra argument. I have done that.

@mpickering
Copy link
Collaborator Author

@andreabedini and I agree on the specification, I have modified the patch based on Andrea's review, can we get a second approval please so I can merge this patch?

applyPackageDbFlags
[GlobalPackageDB]
(projectConfigPackageDBs projectConfigShared)
Cabal.interpretPackageDbFlags False (projectConfigPackageDBs projectConfigShared)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is GlobalPackageDB not needed here? Is it already present in projectConfigPackageDBs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is added by interpretPackageDbFlags.

Copy link
Collaborator

@andreabedini andreabedini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mpickering mpickering added the merge me Tell Mergify Bot to merge label Feb 23, 2024
@mpickering
Copy link
Collaborator Author

Thanks @andreabedini

@mergify mergify bot added the merge delay passed Applied (usually by Mergify) when PR approved and received no updates for 2 days label Feb 25, 2024
In this PR we make the `--package-db` flag apply only to the default
immutable initial package stack rather than also applying to the store
package database.

There are two special package databases which cabal install knows about
and treats specially.

* The store directory, a global cache of installed packages where cabal
  builds and installs packages into.
* The inplace directory, a local build folder for packages, where cabal
  builds local packages in.

It is very important that cabal registers packages it builds into one of
these two locations as there are many assumptions that packages will end
up here.

With the current design of the `--package-db` flag, you are apparently
allowed to override the store location which should have the effect of
making the last package database in the package stack the "store"
directory. Perhaps this works out in theory but practically this
behaviour was broken and things were always registered into the store
directory that cabal knew about. (The assertion in
`ProjectBuilding.UnpackedPackage` was failing (see added test)).

With `--package-db` not being able to modify the location of the store
directory then the interaction of `--package-db`, `--store-dir` and
`--dist-dir` flags become easy to understand.

* `--package-db` modify the initial package database stack, these
  package database will not be mutated by cabal and provide the initial
  package environment which is used by cabal.
* `--store-dir` modify the location of the store directory
* `--dist-dir` modify the location of the dist directory (and hence
  inplace package database)

Treating the flags in this way also fix an assertion failure when
building packages.

Fixes haskell#9678
@mergify mergify bot merged commit 9025af5 into haskell:master Feb 25, 2024
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
attention: needs-review merge delay passed Applied (usually by Mergify) when PR approved and received no updates for 2 days merge me Tell Mergify Bot to merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Assertion failure with --package-db flag
3 participants