我想从.cabal文件中增强flycheck-haskell对自动配置flycheck的支持。
要执行此自动配置,flycheck使用a helper file,其原始策略是读取.cabal文件并使用flattenPackageDescription
。这很简单,但不尊重可能导致问题的条件表达式,例如:使用较新版本的bytestring-builder
软件包时不需要bytestring
。
使用的适当界面似乎是finalizePackageDescription
。这确实有效...但它的类型签名在1.20和1.22之间变化---现在,它不需要CompilerId
,而是现在需要CompilerInfo
。但我希望在此API更改中提供一致的支持。
虽然解决方案通常是使用CPP
宏,但这些宏由Cabal
本身提供,而flycheck
只是使用runhaskell
调用帮助文件,所以我们无法访问它们。
我能想到的唯一选择是创建另一个帮助器以首先获取Cabal
版本信息,然后为我们的{{1}构建适当的CPP
设置调用所以我们可以这样做。这应该有效,但看起来像是一个黑客。
所以我在这里寻找其他选项,这些选项可以让我支持这两个版本的界面,而不必诉诸runhaskell
。
有问题的代码是对CPP
的调用,如下所示:
Distribution.PackageDescription.Configuration.finalizePackageDescription
问题是第四个参数case finalizePackageDescription [] (const True) buildPlatform buildCompilerId [] genericDesc' of
Left e -> putStrLn $ "Issue with package configuration\n" ++ show e
Right (pkgDesc, _) -> print (dumpPackageDescription pkgDesc cabalFile)
将类型从buildCompilerId
更改为CompilerId
。
我已经实现了 - 虽然我很乐意考虑一个更独立的选项---是一个帮助者吐出CompilerInfo
(作为一个s-expr,因为我们正在处理Emacs)如果它是Cabal的最新版本:
-DuseCompilerInfo
然后使用该标志运行原始助手,并有条件地导入新结构,并在上述case语句之前具有以下条件代码:
import Data.Version (Version (Version))
import Distribution.Simple.Utils (cabalVersion)
main :: IO ()
main =
putStrLn $ if cabalVersion >= Version [1,22] []
then "(\"-DuseCompilerInfo\")"
else "()"
它不漂亮,但它有效。