How to Version Imports for Cabal Hook - haskell

I am writing a very simple "hook" for Cabal which works fine with the last version but it stops to work when I "downgrade" Cabal to older versions 1.22, 1.20, etc.
The cause looks due to the path of some modules that keep on change, like for example: import Distribution.Simple.LocalBuildInfo
Is there any way to manage those changes across different versions? Do I need a "CPP" macro (in case which one) or there are better ways to manage it?

Usually yes, code that is dependent on a version of a library manages it via CPP macros, using macros defined by Cabal itself. See http://www.edsko.net/2014/09/13/haskell-cpp-macros/ for some examples. In your case:
#if MIN_VERSION_Cabal(1,22,0)
-- something working in Cabal 1.22 or above
#else
-- something working in Cabal versions prior to 1.22
#endif
It's not ideal, I'll give you that.

Related

Is it possible to apply a patch to external code in Cargo.toml?

I read the Cargo manual about the patch option but it is still unclear to me.
Is it possible to instruct Cargo:
Get the code from this repository.
Apply this patch file (my_cool_change.patch) to that code.
Is making my own fork of the project the only way to do it?
It is not possible to instruct Cargo to do something like "take version 1.2.3 of crate foo-bar from crates.io and apply these arbitrary changes to the source code before compiling it".
The Cargo documentation is not lying to you: you will need to fork the project you wish to change, make the changes however you need, then replace the dependency with your forked version.

cabal repl is too slow

Currently, cabal repl is unusable for me. Typing at the prompt is erratic: a few letters appear, then it seems to hang for 5-10 seconds, only to proceed again afterwards. I suspect it's related to the fact that it loads Alex/Happy generated files (81K and 134K respectively) into the REPL. I don't really need those files for REPL support most of the time. I'm not sure if that's actually the problem, but I don't know what else to try.
I'd like to be able to exclude them from the REPL while still including them in the build process. Even better: can I only use one function from each of those files (lex/parse) somehow?
Edit: I'm seeing this behavior with GHC 7.8.3/Cabal 1.20.0.3 running on OS X 10.9 and a mid-2012 rMBP (Sandy Bridge) with 16GB of RAM. GHC/Cabal was installed via Homebrew.
Edit 2: Cabal file in question
Can you post your .cabal file?
If I understand your situation correctly, here's how I might proceed:
Verify that the alex and happy generated files are causing the slowdown.
If that is the case, consider moving them into a different package so that ghci will load the compiled versions of them.
For #1, I might try replacing the alex and happy generated files with just stubs - skeletal files which contain definitions (= undefined) for only the symbols which are imported by other modules.
I tried reorganizing the code per user5402's answer, but I wasn't able to get much of a speedup, even with code in different base packages.
Instead, I created a .ghci file in the project directory with the following contents:
:set -fobject-code
This loaded compiled versions of modules, with only the exported functions callable. For my uses, this is fine.

How to get source code for all build-depends using cabal?

I generated a new project using Yesod and am trying to go through the source to see how the pieces fit together. I am still a bit unfamiliar with most of the types so I have to keep a browser open where I hoogle/hayoo for types of things.
When I use Intellij for Java development I can usually just jump in to the source code of most of my dependencies. I wanted to try to replicate this for Haskell.
Since I am using vim for Haskell I thought I would just get the source for everything listed in build-depends and then generate a specific cabal_tags file and add that to vim's tags option.
My cabal skills are very rudimentary though. I noticed there is cabal get which can get the source for a package but it seems you need to explicitly specify the package and there doesn't seem to be an option for getting everything specified under build-depends in the .cabal file.

Haskell-mode source navigation for dependencies

I am using haskell-mode for Emacs. I succeeded at creating etags for my haskell project on every save by hasktags, however, the cabal dependencies can not be navigated to this way. So I wonder: Is there a way to make this source code navigation work for cabal dependencies, too? (as it is easily possible for java-maven projects for example..)
You can try haskdogs, which provides a thin wrapper around hasktags and executes it for your imported modules as well as your own code. It maintains a repository of module sources in ~/.haskdogs and indexes into that.
I'm using it with vi and have been quite happy with it so far.

Package versioning clashes in Cabal

Forgive me if this is a FAQ but I'm a bit puzzled about how to get around this problem properly.
I recently downloaded the package TagSoup which installed fine with the latest version 0.12.2
Then I installed the package download-curl which installed fine with the latest version. What I failed to realise was, download-curl depends on TagSoup with a version =< 0.11, so as part of the installation process Cabal downloaded an older version of TagSoup too.
This is a problem because I want to use both libraries (the latest version of TagSoup AND download-curl) - and when you do for some reason GHCI gets in a bit of a mess.
My question is, is there a way of specifying versions in your import statements, i.e.
import Text.Html.TagSoup-0.12.2
or is this a no go? I'm thinking not.
The only way I got around this was to download the download-curl source, modify the .cabal file to use TagSoup-0.12.2 and reinstalled the package with my little "hack" in place which works as I would expect it to - but I don't think this is the solution
Any help would be appreciated
Normally one specifies the required version in the .cabal file. There is an extension syntax for specific package imports (-XPackageImports) but it's usually better to let Cabal deal.
That said, yes, if you need to use both then you enter the dark realm of diamond dependencies. Yours is pretty much the only solution available currently. -XPackageImports is not a good idea here, as trying to use two versions of the same library in the same program probably won't link and almost certainly will dump core at runtime if it does manage to link without duplicate symbols.

Resources