如何在 cabal 或 stack 中禁用版本解析?

How do I disable version parsing in cabal or stack?

我正在为我的项目使用 alternative version numbering approach。我遇到了 cabalstack 的奇怪行为,这让我无法充分享受这种方法的好处。 cabalstack 都强制版本格式为 Int.Int.Int,这不包括我用于分支的另一种版本格式的情况(0.x.x1.x.x1.0.x 等)。

如果我的 .cabal 文件中有行 version: 0.x.x,当 运行 cabal buildUnable to parse cabal file {PROJECT_NAME}.cabal: NoParse "version" 5 时,我会收到 Parse of field 'version' failed. 错误运行 stack init.

有没有办法在 cabalstack 命令上禁用版本解析?有旗帜吗?或者我是否必须向 cabalstack 的开发人员请求这种更改(添加标志、禁用版本解析)?

为什么根本没有解析?它如何帮助构建一个包? cabalstack 是否会在某些事件中自动增加内部版本号?如果是,我在哪里可以阅读更多相关信息?我如何影响 cabalstack 中版本编号递增的实现方式?我希望 haskell 包的开发人员考虑到替代版本编号方法的可能性。

PS。对于所有感兴趣的人,我想快速总结 "weird" 版本号 背后的想法,例如 0.x.x1.x.x1.0.x .我使用带有 x 的版本号来描述允许代码更改的开发流水线,而 1.0.01.1.02.35.46 等版本号用于描述冻结状态开发(准确地说,它们用于 已发布 版本的软件)。注意,0.x.01.x.152.x.23等版本号也是可以的(用于软件的snapshots/builds),它们的意思是该代码库继承自版本号分别为 0.x.x1.x.x2.x.x 的分支。

为什么我需要 0.x.x1.x.x2.x.x 这样的版本号?简而言之,不同数量的 x 意味着不同类型的分支。例如,版本号模式 N.x.x 用于 support 分支,而模式 N.M.x 用于 release 分支。 support 分支背后的想法是它们是由于相应代码库的不兼容而创建的。 Release 分支由于相应代码库中的功能冻结而创建。例如,分支 1.0.x1.1.x1.2.x、... 是由于功能冻结(或 发布 )在分支 1.x.x.

我知道这一切都令人困惑,但我努力建立这种版本编号方法,并继续通过我的演示文稿和其他项目提高对版本编号不一致的认识。一旦您对 pitfalls of semver approach 进行了更多思考,这一切就变得有意义了(您可以在 link 之后找到有关此事的详细幻灯片演示)。但我现在不想为它辩护。目前,我只想 cabalstack 停止对我的项目执行他们的 不合理的 规则。希望你能帮助我。

你不能。版本将被解析为 Version, which is:

data Version = PV0 {-# UNPACK #-} !Word64
             | PV1 !Int [Int]

Stack 使用 Cabal 作为库 but has its own Version type:

newtype Version =
  Version {unVersion :: Vector Word}
  deriving (Eq,Ord,Typeable,Data,Generic,Store,NFData)

cabal 和 stack 都没有办法自定义解析。如果您想使用其他版本类型,则必须编写这些程序的自己的变体。但话又说回来,那时你并没有赢得任何东西:Hackage 和 Stackage 都不会识别你的包的版本。

所以目前 1.x.x 是不可能的。您可以将 x99999999 或类似的东西交换以缓解问题。话虽这么说,但尚不清楚 cabal install 应该安装什么。 99999999 版本?还是最新的稳定版本?

如果你能表达语义,邮件列表上的讨论以及功能请求可能会改变(遥远的)未来的行为,但现在,你要么自己修补程序,要么使用另一个编号方案。

Is there a way to disable version parsing on cabal and stack commands? Is there a flag for it?

没有

Or do I have to request this kind of change (adding flags, disabling version parsing) from the developers of cabal and stack?

你当然可以问,但是outstanding issues太多了,你不太可能得到任何关注。您必须非常 令人信服 -- 足以推翻 20 多年的经验,即当前的版本控制方案基本上是可行的。实际上,如果您希望发生这种情况,您可能必须自己维护这些工具的分支,并提供一个替代位置来托管使用此方案的包。

Why is there any parsing at all? How does it help with building a package?

包指定依赖项,并为每个依赖项指定它们使用的版本范围。然后,构建工具使用约束求解器来选择一组连贯的 package/version 对来满足所有(传递)依赖性。为此,他们必须至少能够检查给定版本是否在给定范围内——这需要至少对版本号进行一点点解析。

Does cabal or stack automatically increment build numbers on some event? If yes, where could I read more about this?

没有什么是自动的。但是你应该看看 Package Version Policy,它作为包维护者之间的社会契约。它让一个软件包维护者说 "I am using bytestring version 0.10.0.1 and it seems to work. I'm being careful about qualifying all my bytestring imports; therefore I can specify a range like >=0.10 && <0.11 and be sure that things will just work, while giving the bytestring maintainer the ability to push security and efficiency updates to my users." 而不必仔细阅读 bytestring 的完整文档,并希望其维护者已经写下了他的版本号的含义。

How could I influence the way version numbering incrementation gets implemented in cabal and stack?

关于你之前关于改变社区做事方式的问题,我认为修改包版本控制政策将非常困难,尤其是像你在这里提议的那样激进的改变。变化越彻底,就必须越谨慎地激励它才能获得牵引力。

老实说,我不知道进行这种激励和讨论的合理地点是什么;也许是 haskell-cafe 邮件列表或类似的。