【发布时间】:2021-07-22 13:17:36
【问题描述】:
简而言之,我的问题是“如何在 cabal 管理的多库 haskell 项目存储库中获得快速的保存-重新测试工作流程?”
我已经尝试了一些事情并进行了一些研究。在了解更多细节之前,请先查看典型的项目 repo 结构,然后将问题分解为更多细节:
存储库开发结构
我从事多个通常具有以下形式的 Haskell 项目:
.
├── foo
│ ├── foo.cabal
│ ├── src
│ ├── unit-test
│ └── ...
├── bar
│ ├── bar.cabal
│ ├── src
│ ├── unit-test
│ └── ...
├── baz
│ ├── baz.cabal
│ ├── src
│ ├── unit-test
│ └── ...
├── stack.yaml
├── cabal.project
├── nix
│ └── ...
└── ...
cabal.project 文件如下所示:
packages:
foo
bar
baz
...
tests: True
run-tests: True
堆栈文件包含基本相同的项目列表和 LTS ID,所以我可以只使用来自 IOHK's haskell.nix 的 stackProject nix 函数来为自己提供一个包含 cabal 等的 nix shell。 (这个问题更多的是关于阴谋集团的处理,所以我认为这里的文本段落只是一个背景说明,我认为与这个堆栈溢出问题无关。)
这个设置允许我在项目的任何地方运行cabal test all,这很棒。这是我在关闭下一个 git 提交之前查看我是否破坏了任何东西的简单方法。
快速保存-重新测试工作流程
在我开始使用 nix 之前,我使用了 stack build/test --watch,这很好,因为我现在可以打开一个 shell,它总是在我在任何地方更改任何内容后重新测试和重建整个项目。
这可以用inotify模拟:
while true; do
inotifywait -e modify -r ./;
cabal test all
done
这不是很快,但它也可以完成工作。
在我了解 GHCID 后,我对它的速度快得惊人感到惊讶。
cabal repl 也很容易使用。
不幸的是(也提到了这个问题,但在How to run test suite in ghcid with cabal? 的评论中没有回答),GHCID 可以在一个特定的单元测试套件上运行,并且不会检测到单元测试应该检查的库上的更改。 (将所有库模块放入 cabal 文件中的单元测试描述中,我认为这是一种丑陋的 hack,我宁愿避免这种情况)
另外,我似乎无法像cabal test all 或stack test --watch 那样在整个存储库 上运行GHCID。
GHCID 的极快速度是我工作流程中真正想要的。
cabal 是一个早在 stack 之前就已经存在的工具,人们如何在他们的多库存储库上工作以快速了解他们在多个库中编辑多个文件后破坏的所有测试用例?如果 GHCID 方式不好用, 方法是什么?
【问题讨论】:
-
“人们如何在他们的多库存储库上工作......” – 我个人最近确实决定放弃 所有 专业工具,只需使用 vanilla nvim 并手动发送每当我想检查时,
cabal test all到它的终端窗口。事实证明,当我完全不依赖任何自动发生的事情时,我的工作效率更高——这只是让我等待制表符完成或其他什么,而不可预测性意味着我没有充分利用编辑器命令自己。 -
我认为获得性能的最有效方法是取消所有抽象,将所有模块视为一个直接加载到 ghcid 中的大库。您可以使用
.ghci文件或组合所有这些文件的虚拟库(包括测试套件)来做到这一点。
标签: unit-testing haskell cabal inotify