I want to enhance flycheck-haskell's support for auto-configuring flycheck from your .cabal file.
To do this autoconfiguration, flycheck uses a helper file whose original strategy was to read the .cabal file and use flattenPackageDescription
. This was simple, but does not respect conditional expressions, which can cause problems with, e.g. not needing bytestring-builder
when using newer version of the bytestring
package.
The appropriate interface to use would seem to be finalizePackageDescription
. This does work...but its type signature changed between 1.20 and 1.22---now, instead of taking a CompilerId
, it now takes a CompilerInfo
. Yet I would like to provide consistent support across this API change.
While the solution for this is generally to use CPP
macros, those macros are provided by Cabal
itself, and flycheck
is simply invoking the helper file with runhaskell
, so we don't have access to them.
The only option I can think of would be to create another helper to first get the Cabal
version information, and then construct appropriate CPP
settings for our runhaskell
invocation so we can do things that way. That should work, but seems like a hack.
So I'm here looking for other options that would allow me to support both versions of the interface, without having to resort to CPP
.
The code in question is a call to Distribution.PackageDescription.Configuration.finalizePackageDescription
, like so:
case finalizePackageDescription [] (const True) buildPlatform buildCompilerId [] genericDesc' of
Left e -> putStrLn $ "Issue with package configuration\n" ++ show e
Right (pkgDesc, _) -> print (dumpPackageDescription pkgDesc cabalFile)
The problem is that the fourth parameter, buildCompilerId
changed type from CompilerId
to CompilerInfo
.
What I have implemented---though I would be happy to consider a more self-contained option---is a helper that spits out -DuseCompilerInfo
(as an s-expr, since we're dealing with Emacs) if it's a sufficiently recent version of Cabal:
import Data.Version (Version (Version))
import Distribution.Simple.Utils (cabalVersion)
main :: IO ()
main =
putStrLn $ if cabalVersion >= Version [1,22] []
then "(\"-DuseCompilerInfo\")"
else "()"
The original helper is then run with the flag, and conditionally imports the new structures, as well as having the following conditional code just before the case statement above:
#ifdef useCompilerInfo
buildCompilerId = unknownCompilerInfo (CompilerId buildCompilerFlavor compilerVersion) NoAbiTag
#else
buildCompilerId = CompilerId buildCompilerFlavor compilerVersion
#endif
It's not beautiful, but it works.