堆栈的 package.yaml 与 stack.yaml

Stack's package.yaml vs stack.yaml

Stack has supported hpack's package.yaml configuration files since at least around this commit,据我所知,但关于它与 stack.yaml 文件之间差异的文档并不多。

我找到的少数几个谈论它的链接之一是 this documentation,它说:

package.yaml is a file format supported by hpack. It adds some niceties on top of cabal. For example, hpack has YAML syntax support and will automatically generate of exposed-modules lists. However, it's just a frontend to cabal package files.

因此,package.yaml 似乎提供了 *.cabal 文件配置能力的超集,就像 stack.yaml 文件一样。


documentation here表示stack.yaml是配置文件:

Next, let's look at our stack.yaml file, which gives our project-level settings.

...and later says package.yaml 用于存储依赖关系:

To tell stack to use text, you need to add it to your package.yaml file — specifically in your dependencies section...

,但遗憾的是没有说明这两个文件之间的区别。

我一直在为我的所有项目配置使用 package.yaml,并且从未使用过 stack.yaml


那么,stack的package.yamlstack.yaml文件是什么关系呢? If/when他们的职责重叠,使用哪个更好?

So from this, it seems like package.yaml provides a superset of the *.cabal file's configuration ability, like the stack.yaml file also does.

stack.yaml 不提供 *.cabal 配置的超集。


*.cabal文件是package-level配置。它可以由 hpackpackage.yaml 生成。此配置提供有关包的基本信息:依赖项、导出的组件(库、可执行文件、测试套件)和构建过程的设置(预处理器、自定义 Setup.hs)。许多项目也不使用 hpack 并且没有 package.yaml,只有 *.cabal 文件。

stack.yaml 文件是 project-level 配置,它指定了一个特定的环境,使构建可重现,固定版本的编译器和依赖项。这通常由解析器指定(例如 lts-11.4)。

stack.yamlpackage.yaml 不是多余的。 package.yaml 指定需要哪些依赖项。 stack.yaml 表示一种一致解决依赖关系的方法(特定包版本,and/or 从哪里获取它,例如:在 Hackage 上,远程存储库或本地目录)。

stack.yaml 对开发人员最有用:我们不希望我们的构建突然中断,因为在处理另一个项目时依赖项升级了,因此我们将所有内容都固定为 stack.yaml。此文件对可能有外部约束的用户用处不大(通常,版本已由某些发行版修复)。

  • 在很多情况下,只需在stack.yaml中指定解析器就足够了。因此新 stack 用户通常不需要担心配置 stack.yaml.

  • 解析器指定一组具有特定版本的精选包(标准包列在 stackage.org 上)。如果所选解析器缺少包的依赖项,则它必须列在 stack.yamlextra-deps 字段中。

  • 一个项目可以跨越多个包,因此被添加到 stack.yamlpackages 字段中,因此它们可以在一个公共环境中构建并依赖于每个包其他.

  • 另一个常见的用例是创建许多 stack.yaml(具有不同的名称)以轻松测试各种配置(例如,GHC 版本或包标志)。