Hdevtools cabal support

Hi, I'm pretty new to Haskell, but was doing Haskell development for several month. I'm fan of Vim editor and was happy to find out that there are good tools to support Haskell development with Vim, e.g. vim-hdevtools. But it turned out that it not of much use in my project where we rely on Cabal packages and sandboxes. As part of scratching own itch I have implemented support for Cabal packages for Hdevtools. I invite everyone interested to try, review and provide feedback on this. The patch is not yet merged into master branch, so to install it you need to check it out from my repository: git clone https://github.com/maximkulkin/hdevtools.git cd hdevtools git checkout cabal-support cabal install So, to be able to use hdevtools with Cabal, you just need to run hdevtools from inside your Cabal project, e.g. hdevtools check src/MyFile.hs hdevtools info src/MyOtherFile.hs DoThat Hope this will save someone's day. Max

Hi Maxim,
I'm pretty new to Haskell, but was doing Haskell development for several month. I'm fan of Vim editor and was happy to find out that there are good tools to support Haskell development with Vim, e.g. vim-hdevtools. But it turned out that it not of much use in my project where we rely on Cabal packages and sandboxes.
You don't need to modify hdevtools to get support for cabal sandboxes. But you have to tell hdevtools the position of the package database of the cabal sandbox. For vim you could use something like: function! s:FindCabalSandbox() let l:sandbox = finddir('.cabal-sandbox', './;') let l:absSandbox = fnamemodify(l:sandbox, ':p') return l:absSandbox endfunction function! s:FindCabalSandboxPackageConf() return glob(s:FindCabalSandbox() . '*-packages.conf.d') endfunction function! s:HaskellSourceDir() return fnamemodify(s:FindCabalSandbox(), ':h:h') . '/src' endfunction let g:hdevtools_options = '-g-package-conf=' . s:FindCabalSandboxPackageConf() let g:hdevtools_options .= ' ' . '-g-i' . s:HaskellSourceDir() This also assumes, that your Haskell source code is contained in a directory named 'src' which lies in the same directory then your projects cabal file. Using hdevtools this way is more generic than modify it, because this solution also works for cabal-dev or any other package database. Greetings, Daniel

Hi Maxim,
I'm pretty new to Haskell, but was doing Haskell development for several month. I'm fan of Vim editor and was happy to find out that there are good tools to support Haskell development with Vim, e.g. vim-hdevtools. But it turned out that it not of much use in my project where we rely on Cabal packages and sandboxes.
You don't need to modify hdevtools to get support for cabal sandboxes. But you have to tell hdevtools the position of the package database of the cabal sandbox. For vim you could use something like: function! s:FindCabalSandbox() let l:sandbox = finddir('.cabal-sandbox', './;') let l:absSandbox = fnamemodify(l:sandbox, ':p') return l:absSandbox endfunction function! s:FindCabalSandboxPackageConf() return glob(s:FindCabalSandbox() . '*-packages.conf.d') endfunction function! s:HaskellSourceDir() return fnamemodify(s:FindCabalSandbox(), ':h:h') . '/src' endfunction let g:hdevtools_options = '-g-package-conf=' . s:FindCabalSandboxPackageConf() let g:hdevtools_options .= ' ' . '-g-i' . s:HaskellSourceDir() This also assumes, that your Haskell source code is contained in a directory named 'src' which lies in the same directory then your projects cabal file. Using hdevtools this way is more generic than modify it, because this solution also works for cabal-dev or any other package database. Greetings, Daniel

Oh, thank you, Sir, for pointing that out. I was aware of this hackish vim-script. I even tried to use that but fell into lots of corner cases and dropped. It does not handle inter-package dependencies, haskell language extensions, different code or sandbox layout. Although currently it has limitations (locked to particular ghc and cabal versions) I personally find it way more easy to use. I believe, with release of GHC-7.8, Cabal-1.18 will become ubiquitous, bringing sandbox support out of the box. With evolving of the compiler I do not see why dev tools shouldn't evolve too. If someone uses cabal-dev, I would happy to see him adding support for it to hdevtools. BTW, cabal-dev just changes the sandbox layout, other things are left unchanged, so you can still benefit from having cabal support in hdevtools. You just need to pass location of cabal-dev sandboxed package db explicitly (via "-g" option). On Fri, Feb 21, 2014 at 2:11 PM, Daniel Trstenjak < daniel.trstenjak@gmail.com> wrote:
Hi Maxim,
I'm pretty new to Haskell, but was doing Haskell development for several month. I'm fan of Vim editor and was happy to find out that there are good tools to support Haskell development with Vim, e.g. vim-hdevtools. But it turned out that it not of much use in my project where we rely on Cabal packages and sandboxes.
You don't need to modify hdevtools to get support for cabal sandboxes. But you have to tell hdevtools the position of the package database of the cabal sandbox.
For vim you could use something like:
function! s:FindCabalSandbox() let l:sandbox = finddir('.cabal-sandbox', './;') let l:absSandbox = fnamemodify(l:sandbox, ':p') return l:absSandbox endfunction
function! s:FindCabalSandboxPackageConf() return glob(s:FindCabalSandbox() . '*-packages.conf.d') endfunction
function! s:HaskellSourceDir() return fnamemodify(s:FindCabalSandbox(), ':h:h') . '/src' endfunction
let g:hdevtools_options = '-g-package-conf=' . s:FindCabalSandboxPackageConf() let g:hdevtools_options .= ' ' . '-g-i' . s:HaskellSourceDir()
This also assumes, that your Haskell source code is contained in a directory named 'src' which lies in the same directory then your projects cabal file.
Using hdevtools this way is more generic than modify it, because this solution also works for cabal-dev or any other package database.
Greetings, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hi Maxim,
I was aware of this hackish vim-script. I even tried to use that but fell into lots of corner cases and dropped. It does not handle inter-package dependencies, haskell language extensions, different code or sandbox layout.
It's definitively nice to reuse the information of the cabal file, I just don't like the coupling of tools that much. Also there seems to be duplicate effort for supporting cabal sandboxes in ghc-mod and hdevtools. It would be nice to have a tool that extracts the ghc relevant options from the cabal file which then could be used by ghc-mod, hdevtools or any other tool that wants to use ghc in conjunction with cabal. Getting the ghc options right you also have to use the right cabal section (which executable, library, which test suite ...), so a seperate tool could nicely support this. Greetings, Daniel

In terms of using the right section of cabal, in the dev/editor environment you actually need to union of all the cabal targets, so all the various hs-src directories etc are in scope. Alan On Fri, Feb 21, 2014 at 2:05 PM, Daniel Trstenjak < daniel.trstenjak@gmail.com> wrote:
Hi Maxim,
I was aware of this hackish vim-script. I even tried to use that but fell into lots of corner cases and dropped. It does not handle inter-package dependencies, haskell language extensions, different code or sandbox layout.
It's definitively nice to reuse the information of the cabal file, I just don't like the coupling of tools that much.
Also there seems to be duplicate effort for supporting cabal sandboxes in ghc-mod and hdevtools.
It would be nice to have a tool that extracts the ghc relevant options from the cabal file which then could be used by ghc-mod, hdevtools or any other tool that wants to use ghc in conjunction with cabal.
Getting the ghc options right you also have to use the right cabal section (which executable, library, which test suite ...), so a seperate tool could nicely support this.
Greetings, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hi Alan, On Fri, Feb 21, 2014 at 02:09:28PM +0200, AlanKim Zimmerman wrote:
In terms of using the right section of cabal, in the dev/editor environment you actually need to union of all the cabal targets, so all the various hs-src directories etc are in scope.
You might get an issue by doing it that way, just think about two executables having modules with the same name. I think the "right" way might be to find the associated cabal target for the current source file. But I don't know if it's possible to always get a unique cabal target. Greetings, Daniel

What I am doing in HaRe (as a trial at this stage) is to load the module graph for each cabal target in turn, and take the union of all non-Main modules. This will work for a large proportion of cabal files. Where something special is going on in terms of e.g. flags pulling on one of two mutually exclusive files with the same name, a different approach will be needed, probably by specifying how to break the tie in a config section for the tool. But I agree that a separate tool could be useful for this, I am pretty sure BuildWrapper is wrestling with the same problem. Alan On Fri, Feb 21, 2014 at 2:22 PM, Daniel Trstenjak < daniel.trstenjak@gmail.com> wrote:
Hi Alan,
On Fri, Feb 21, 2014 at 02:09:28PM +0200, AlanKim Zimmerman wrote:
In terms of using the right section of cabal, in the dev/editor environment you actually need to union of all the cabal targets, so all the various hs-src directories etc are in scope.
You might get an issue by doing it that way, just think about two executables having modules with the same name.
I think the "right" way might be to find the associated cabal target for the current source file.
But I don't know if it's possible to always get a unique cabal target.
Greetings, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

It would be nice to have a tool that extracts the ghc relevant options from the cabal file which then could be used by ghc-mod, hdevtools or any other tool that wants to use ghc in conjunction with cabal.
Personally, I would like that very much, and I would be an active user. Why not just a parameter, much like cabal own behaviour: cabal build - sane default cabal build exe:whatever - build executable whatever babal build lib:whatever - build executable whatever Its not really critical that the default is a cover all scenario, as long as you have those other options. Then you could just configure an editor (vim) setting to manually tell it what should it do. I would prefer that, even if it meant a little more configuration work, than having a 'merge all' situation that does, typically, more harm than good.
I think the "right" way might be to find the associated cabal target for the current source file.
I also have doubts that this is possible.
Cheers,
João
2014-02-21 12:22 GMT+00:00 Daniel Trstenjak
Hi Alan,
On Fri, Feb 21, 2014 at 02:09:28PM +0200, AlanKim Zimmerman wrote:
In terms of using the right section of cabal, in the dev/editor environment you actually need to union of all the cabal targets, so all the various hs-src directories etc are in scope.
You might get an issue by doing it that way, just think about two executables having modules with the same name.
I think the "right" way might be to find the associated cabal target for the current source file.
But I don't know if it's possible to always get a unique cabal target.
Greetings, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Having to manually set up cabal target explicitly won't work if you e.g.
develop a library and unit tests for it and switch between test and library
modules (which are obviously different targets in cabal file).
I think the best approach would be to determine a first cabal target source
file belongs to and using it. This won't expose problems that would occur
bulding other targets that also use that file, but I guess it is ok.
Also, I was thinking about adding suport for passing cabal options to allow
e.g. using different flags.
On Fri, Feb 21, 2014 at 4:37 PM, João Cristóvão
It would be nice to have a tool that extracts the ghc relevant options from the cabal file which then could be used by ghc-mod, hdevtools or any other tool that wants to use ghc in conjunction with cabal.
Personally, I would like that very much, and I would be an active user.
Why not just a parameter, much like cabal own behaviour:
cabal build - sane default cabal build exe:whatever - build executable whatever babal build lib:whatever - build executable whatever
Its not really critical that the default is a cover all scenario, as long as you have those other options. Then you could just configure an editor (vim) setting to manually tell it what should it do.
I would prefer that, even if it meant a little more configuration work, than having a 'merge all' situation that does, typically, more harm than good.
I think the "right" way might be to find the associated cabal target for the current source file.
I also have doubts that this is possible.
Cheers, João
2014-02-21 12:22 GMT+00:00 Daniel Trstenjak
: Hi Alan,
On Fri, Feb 21, 2014 at 02:09:28PM +0200, AlanKim Zimmerman wrote:
In terms of using the right section of cabal, in the dev/editor environment you actually need to union of all the cabal targets, so all the various hs-src directories etc are in scope.
You might get an issue by doing it that way, just think about two executables having modules with the same name.
I think the "right" way might be to find the associated cabal target for the current source file.
But I don't know if it's possible to always get a unique cabal target.
Greetings, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

This is what I do currently, although I'm not sure if this won't cause
troubles.
As of ghc-mod: as far as I understand (didn't dig into this much, just read
in hdevtools documentation), hdevtools is just ghc-mod with client-server
architecture, so that it supports incremental recompiles (and thus faster
for subsequent invocations). If this is so, I do not see reason to continue
supporting ghc-mod.
On Fri, Feb 21, 2014 at 4:09 PM, AlanKim Zimmerman
In terms of using the right section of cabal, in the dev/editor environment you actually need to union of all the cabal targets, so all the various hs-src directories etc are in scope.
Alan
On Fri, Feb 21, 2014 at 2:05 PM, Daniel Trstenjak < daniel.trstenjak@gmail.com> wrote:
Hi Maxim,
I was aware of this hackish vim-script. I even tried to use that but fell into lots of corner cases and dropped. It does not handle inter-package dependencies, haskell language extensions, different code or sandbox layout.
It's definitively nice to reuse the information of the cabal file, I just don't like the coupling of tools that much.
Also there seems to be duplicate effort for supporting cabal sandboxes in ghc-mod and hdevtools.
It would be nice to have a tool that extracts the ghc relevant options from the cabal file which then could be used by ghc-mod, hdevtools or any other tool that wants to use ghc in conjunction with cabal.
Getting the ghc options right you also have to use the right cabal section (which executable, library, which test suite ...), so a seperate tool could nicely support this.
Greetings, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Maxim Kulkin wrote:
I'm pretty new to Haskell, but was doing Haskell development for several month. I'm fan of Vim editor and was happy to find out that there are good tools to support Haskell development with Vim, e.g. vim-hdevtools. But it turned out that it not of much use in my project where we rely on Cabal packages and sandboxes.
As part of scratching own itch I have implemented support for Cabal packages for Hdevtools.
Sandboxes aside, there seem to be plenty of reasons for hdevtools to integrate with cabal. To use hdevtools in one of my projects, I have to run it like this. hdevtools check git-annex.hs -g -cpp -g -i -g -idist/build/git-annex/git-annex-tmp -g -i. -g -idist/build/autogen -g -Idist/build/autogen -g -Idist/build/git-annex/git-annex-tmp -g -IUtility -g -DWITH_TESTSUITE -g -DWITH_S3 -g -DWITH_ASSISTANT -g -DWITH_INOTIFY -g -DWITH_DBUS -g -DWITH_PAIRING -g -DWITH_XMPP -g -optP-include -g -optPdist/build/autogen/cabal_macros.h -g -odir -g dist/build/git-annex/git-annex-tmp -g -hidir -g dist/build/git-annex/git-annex-tmp -g -stubdir -g dist/build/git-annex/git-annex-tmp -g -threaded -g -Wall -g -XHaskell98 -g -XPackageImports This was obviously not an easy command line to come up with, and it frequently breaks. And all of it should be able to be derived from the cabal file. So, I am excited about your branch. But it doesn't seem to have the smarts to avoid needing that yet. joey@darkstar:~/src/git-annex>~/tmp/hdevtools/dist/build/hdevtools/hdevtools --version hdevtools: version 0.1.0.6 (ghc-7.6.3-x86_64-linux, cabal-1.16.0) joey@darkstar:~/src/git-annex>~/tmp/hdevtools/dist/build/hdevtools/hdevtools check git-annex.hs Utility/DiskFree.hs:61:2: warning: #warning Building without disk free space checking support [-Wcpp] #warning Building without disk free space checking support ^ Logs/Unused.hs:97:0: error: missing binary operator before token "(" #if MIN_VERSION_directory(1,2,0) ^ Logs/Unused.hs:102:2: warning: #warning foo [-Wcpp] #warning foo ^ phase `C pre-processor' failed (exitcode = 1) - exit 1 -- see shy jo

Thanks for the support Joey!
Could you send me the full list of GHC options that your application is
built with. You can do that by issuing "cabal build -v" and then finding
options that you ghc is run with. I do not need list of your modules or
your defines though. That would help.
This is one downside of using all GHC options. I have already done
workaround for -Werror and seems like there are other situations that cause
problems (looks like CPP warnings for some reason cause preprocessing fail).
On Sat, Feb 22, 2014 at 2:07 AM, Joey Hess
I'm pretty new to Haskell, but was doing Haskell development for several month. I'm fan of Vim editor and was happy to find out that there are good tools to support Haskell development with Vim, e.g. vim-hdevtools. But it turned out that it not of much use in my project where we rely on Cabal
Maxim Kulkin wrote: packages and sandboxes.
As part of scratching own itch I have implemented support for Cabal
packages for Hdevtools.
Sandboxes aside, there seem to be plenty of reasons for hdevtools to integrate with cabal.
To use hdevtools in one of my projects, I have to run it like this.
hdevtools check git-annex.hs -g -cpp -g -i -g -idist/build/git-annex/git-annex-tmp -g -i. -g -idist/build/autogen -g -Idist/build/autogen -g -Idist/build/git-annex/git-annex-tmp -g -IUtility -g -DWITH_TESTSUITE -g -DWITH_S3 -g -DWITH_ASSISTANT -g -DWITH_INOTIFY -g -DWITH_DBUS -g -DWITH_PAIRING -g -DWITH_XMPP -g -optP-include -g -optPdist/build/autogen/cabal_macros.h -g -odir -g dist/build/git-annex/git-annex-tmp -g -hidir -g dist/build/git-annex/git-annex-tmp -g -stubdir -g dist/build/git-annex/git-annex-tmp -g -threaded -g -Wall -g -XHaskell98 -g -XPackageImports
This was obviously not an easy command line to come up with, and it frequently breaks. And all of it should be able to be derived from the cabal file.
So, I am excited about your branch. But it doesn't seem to have the smarts to avoid needing that yet.
joey@darkstar:~/src/git-annex>~/tmp/hdevtools/dist/build/hdevtools/hdevtools --version hdevtools: version 0.1.0.6 (ghc-7.6.3-x86_64-linux, cabal-1.16.0) joey@darkstar:~/src/git-annex>~/tmp/hdevtools/dist/build/hdevtools/hdevtools check git-annex.hs Utility/DiskFree.hs:61:2: warning: #warning Building without disk free space checking support [-Wcpp] #warning Building without disk free space checking support ^ Logs/Unused.hs:97:0: error: missing binary operator before token "(" #if MIN_VERSION_directory(1,2,0) ^ Logs/Unused.hs:102:2: warning: #warning foo [-Wcpp] #warning foo ^ phase `C pre-processor' failed (exitcode = 1) - exit 1
-- see shy jo

On 22/02/14 04:46, Maxim Kulkin wrote:
Thanks for the support Joey!
Could you send me the full list of GHC options that your application is built with. You can do that by issuing "cabal build -v" and then finding options that you ghc is run with. I do not need list of your modules or your defines though. That would help.
This is one downside of using all GHC options. I have already done workaround for -Werror and seems like there are other situations that cause problems (looks like CPP warnings for some reason cause preprocessing fail).
Does ghc-mod handle this case? It has some code for automatically finding a project's cabal file and/or sandbox. Also the latest Cabal library has some functionality (related to what happens when you call "cabal repl") that both hdevtools and ghc-mod (and even my project ghc-imported-from) could benefit from. There's no reason to duplicate the work that is already done in Cabal for working out GHC options, cabal package options, etc. -- Carlo Hamalainen http://carlo-hamalainen.net

As far as I have understood ghc-mod code for supporting Cabal, they do parse cabal file, but rather cherry pick individual options and generate GHC options manually. In hdevtools I use the code from Cabal to generate the same set of GHC options that will be use by Cabal itself to compile code in package. Thus, ghc-mod do not have problems with filtering -Werror, but though it doesn't handle extra options and/or flags (e.g. -Dsymbol CLI options).
Not sure what new functionality in Cabal you are referring to, but I should notice that currently Hdevtools is built with Cabal 1.16 library and not with 1.18. Thus I had to reimplement sandbox detection. The problem is that Hdevtools depend on "ghc" package and "ghc" (for some reason) depend on "Cabal" (and thus the version is a bit outdated). With release of GHC-7.8 Cabal 1.18 will be official and Hdevtools could start using it's built-in functionality for detecting sandbox etc.
On Feb 22, 2014, at 13:21, Carlo Hamalainen
On 22/02/14 04:46, Maxim Kulkin wrote:
Thanks for the support Joey!
Could you send me the full list of GHC options that your application is built with. You can do that by issuing "cabal build -v" and then finding options that you ghc is run with. I do not need list of your modules or your defines though. That would help.
This is one downside of using all GHC options. I have already done workaround for -Werror and seems like there are other situations that cause problems (looks like CPP warnings for some reason cause preprocessing fail).
Does ghc-mod handle this case? It has some code for automatically finding a project's cabal file and/or sandbox.
Also the latest Cabal library has some functionality (related to what happens when you call "cabal repl") that both hdevtools and ghc-mod (and even my project ghc-imported-from) could benefit from. There's no reason to duplicate the work that is already done in Cabal for working out GHC options, cabal package options, etc.
-- Carlo Hamalainen http://carlo-hamalainen.net
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Maxim Kulkin wrote:
Thanks for the support Joey!
Could you send me the full list of GHC options that your application is built with. You can do that by issuing "cabal build -v" and then finding options that you ghc is run with. I do not need list of your modules or your defines though. That would help.
Sure, with the -package-id's left out, it is: /usr/bin/ghc --make -fbuilding-cabal-package -odir dist/build/git-annex/git-annex-tmp -hidir dist/build/git-annex/git-annex-tmp -stubdir dist/build/git-annex/git-annex-tmp -i -idist/build/git-annex/git-annex-tmp -i. -idist/build/autogen -Idist/build/autogen -Idist/build/git-annex/git-annex-tmp -IUtility -optP-DWITH_CLIBS -optP-DWITH_TESTSUITE -optP-DWITH_TDFA -optP-DWITH_CRYPTOHASH -optP-DWITH_S3 -optP-DWITH_WEBDAV -optP-DWITH_ASSISTANT -optP-DWITH_INOTIFY -optP-DWITH_DBUS -optP-DWITH_WEBAPP -optP-DWITH_PAIRING -optP-DWITH_XMPP -optP-DWITH_DNS -optP-DWITH_FEED -optP-DWITH_QUVI -optP-DWITH_TAHOE -optP-include -optPdist/build/autogen/cabal_macros.h -hide-all-packages -package-db dist/package.conf.inplace (You can also find git-annex's source on hackage.) -- see shy jo
participants (6)
-
AlanKim Zimmerman
-
Carlo Hamalainen
-
Daniel Trstenjak
-
Joey Hess
-
João Cristóvão
-
Maxim Kulkin