haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.62k stars 697 forks source link

`cabal v2-install xyz` does an `sdist` when run from directory with `.cabal` file #7434

Open andreasabel opened 3 years ago

andreasabel commented 3 years ago

On would think that cabal v2-install xyz where xyz is a package on hackage only builds and installs xyz, but it does other things if the current directory happens to contain a cabal project:

$ cabal install happy
Wrote tarball sdist to
/Users/abel/project/open-source/bnfc/dist-newstyle/sdist/BNFC-2.9.2.tar.gz
Resolving dependencies...
Build profile: -w ghc-8.10.5 -O1
In order, the following will be built (use -v for more details):
 - happy-1.20.0 (exe:happy) (requires build)
...
$ cabal --version
cabal-install version 3.5.0.0
compiled using version 3.5.0.0 of the Cabal library 
phadej commented 3 years ago

This is by design, if you want to ignore project use:

% cabal install --help|grep -- -z
 -z --ignore-project                                     Ignore local project
Mikolaj commented 3 years ago

@andreasabel: any idea how to help the user in this case? Any warning, explanation, "Project found, so taking it into account"? Is the -z option enough?

andreasabel commented 3 years ago

In the current use-case, the installation of the executable happy is not affected by the project [I strongly hope], nor is the project (essentially) affected by the installation of happy. So I do not understand how the project is "taken into account", nor why sdist is executed in this situation when it is orthogonal to the purpose (to install the executable happy). So, I don't understand the design here.

My preference would be to fix the design, rather than letting cabal state something like:

I am now creating the tarball for your project. I know that it is not what you meant me to do, but I am doing it anyway. If you want to stop me from doing this, give option -z.

Mikolaj commented 3 years ago

I'd like to learn the complete rationale for the design, too, but one case I'm using right now is

repository head.hackage.ghc.haskell.org

in cabal.project.local, which tells cabal to use the hackage version adjusted to the next (HEAD) version of GHC when compiling my project (e.g., to test that it works with the new GHC, e.g., if it's supposed to be bundled with GHC or released in tandem). In particular, sometimes happy may need a breaking change for the new GHC, so I definitely need the new happy, not the one from ordinary Hackage.

I suppose a lot of other options from cabal.project and cabal.project.local may be relevant, e.g., any related to cross-compilation (do you want happy from the build, host or target architecture?) or to adding specific flags to packages (extra cryptography features, avoiding certain dependencies, etc.).

@andreasabel: Does it sound like a sensible feature for some users/uses now?

jneira commented 3 years ago

Definitely install the executable may be affected by project specific options but it does not seem unreasonable that its install will not trigger a sdist of local project packages, even if those packages are dependencies of the executable being installed (although is not the case at hand).

fgaz commented 3 years ago

I'm also using this feature, and I think it's sensible that install is affected like the other commands. After all, if we say install x and x is in the current project, we surely want to install that one!

As for the unnecessary sdists: v2-install currently just sdists everything in the project. I think it's done that way simply because it's a simpler behavior (and it really becomes more complex if you want to keep both the selective sdist and the install-from-sdist). @typedrat may know more

Mikolaj commented 3 years ago

Oh, I didn't know that cabal install foo installs from current directory if foo.cabal is present [edit: and also if it's in a subdirectory and mentioned in cabal.project?], as opposed to from Hackage (or whatever package repository is specified in config files). I hope it's communicated clearly to the user when the compilation starts? [Edit: I guess I would be expecting something like cabal install ./foo to indicate the package is to be taken from local directory, but OTOH using vacuous paths to signal intent is not a good idea]