How to use "cabal-dev ghci" with a non-sandbox, non-global (user?) package?
Asked Answered
E

1

8

I'm trying out cabal-dev for a project I'm working on; the project is a library, and cabal-dev does a great job of building a sandboxed version of it - but I'm having trouble with part of my workflow...

I have a script, scratch.hs, which (pre-cabal-dev) I would load into ghci for trying stuff out. The contents of scratch.hs change over time depending on what feature I'm working on, of course. scratch.hs isn't part of the library codebase, it's just my personal scratchspace while I'm working on it.

Now, in order to get a ghci session with my sandbox loaded, I can just cabal-dev ghci, and then load scratch.hs into that. The problem is that this (by design, and sensibly) excludes my user package database, so if scratch.hs references modules from packages which aren't in my library's build-depends (which is not unreasonable - it's not part of the library after all), those packages aren't visible, and so I get an error such as:

scripts/scratch.hs:8:8:
    Could not find module `Data.Aeson.Generic':
      It is a member of the hidden package `aeson-0.3.2.11'.
      Perhaps you need to add `aeson' to the build-depends in your .cabal file.
      Use -v to see a list of the files searched for.
Failed, modules loaded: none.

where, in this case, scratch.hs wants to import Data.Aeson.Generic but aeson is not in my library's build-depends (quite properly), but is in my user package database.

So how can I work around this? I can imagine answers in either of these categories, but maybe there are categories I've missed:

  1. A way to (selectively) use packages from my user package database in conjunction with the sandbox created by cabal-dev. (Perhaps rolling my own cabal-dev ghci style script?)

  2. A suggestion on how to improve my workflow so the problem just goes away.

I know I could just install the package globally, but I'm reluctant to pollute my global package database in this manner (and cabal-dev discourages this explicitly).

Many thanks for all advice.

Exieexigency answered 15/9, 2011 at 14:8 Comment(4)
I wonder... can you :set -package from within ghci? (Or whatever the name of the option is that chooses your package database?)Housel
slaps forehead - why didn't I think of that? Yes, that works - thanks. I can even add it to .ghci and have it happen automatically. Thanks, Daniel!Exieexigency
Oops, tell a lie. No, that doesn't work. It appeared to work earlier, but that was because my project's test-suite uses aeson, so it was referenced in my .cabal file and thus brought in to the sandbox though not, it seems, implicitly loaded by cabal-dev ghci, which is why I needed :set -package aeson to load it. If I remove that, then in fact :set -package aeson doesn't load the user package database version ("cannot satisfy -package aeson"), so I'm back where I started (except that everybody who's viewed this page in the last 3 hours thinks the problem is solved).Exieexigency
Looking at the GHC manual, it turns out that the flag I meant is called -package-conf, not -package. However, I just tested it, and that doesn't seem to work, either. Sorry.Housel
P
8

I think the simplest solution is just to install the things that you need into the sandbox. For example, if you need aeson for your interactive script:

~/myproject$ cabal-dev install aeson
~/myproject$ cabal-dev ghci

Then :set -package aeson should work in ghci.

If that's inadequate, you have a lot of dependencies you want to use from your user package database, and you don't need ghci to be invoked with the other flags that your cabal file sets for invoking ghc, then you can invoke non-sandboxed ghci with access to the packages from the sandbox as well as your user and global packages. For example (for GHC 7.0.3):

~/myproject$ GHC_PACKAGE_PATH=./cabal-dev/packages-7.0.3: ghci

(Note both the colon at the end of the GHC_PACKAGE_PATH and the space between that and ghci.)

Pic answered 19/9, 2011 at 16:23 Comment(2)
Awesome - many thanks. The second suggestion is working for me. :-) (Any idea what happens if sandbox and user have the same package installed, btw?) The first suggestion also looks good (maybe better) but isn't viable for me at this time: there's a bug in double-conversion (a dependency of blaze-textual, which is a dependency of aeson) which prevents it being used with ghci; there is a workaround but it doesn't work with cabal-dev so I won't be able to install aeson into my sandbox at this time.Exieexigency
Works with cabal 1.18 sandbox feature too with a little change: GHC_PACKAGE_PATH=.cabal-sandbox/x86_64-linux-ghc-7.4.1-packages.conf.d: ghciKroon

© 2022 - 2024 — McMap. All rights reserved.