opam 新功能:本地切换

在 opam 2.0 中,我们想要改进的领域之一是切换的处理方式。在 opam 1.2 中,它们只能通过名称访问(默认情况下是 OCaml 版本),并且始终存储在~/.opam/<name>中。这很好,但在存在很多切换时会变得有点麻烦,因为没有办法对它们进行排序或将它们与特定项目关联。

关于切换的提醒

对于不熟悉 opam 中的切换的人来说,切换是指带有自己的编译器和已安装包集的独立前缀。opam switch命令允许创建和删除切换,以及选择当前活动的切换,在那里操作(如opam install)将执行。

它们的用途包括轻松地在 OCaml 版本或库版本之间切换,将不兼容的包分别安装,但同时安装,在不破坏您的“主”环境的情况下运行测试,以及,通常,将环境分离以处理不同的项目。

您也可以使用以下命令为单个命令选择特定切换:

opam install foo --switch other

或者甚至为单个 shell 会话选择:

eval $(opam env --switch other)

opam 2.0 在此基础上增加了创建所谓本地切换的可能性,这些切换存储在您选择的目录下。这使用户可以重新控制切换的组织方式,并且清除该目录是摆脱切换的安全方法。

在项目中使用

这是主要的预期用途:用户可以在项目的源代码中定义一个切换,专门用于该项目。一个很好的副作用是,如果在当前目录或父目录中检测到“本地切换”,opam 会自动选择它。只是不要忘记在运行make之前运行eval $(opam env)以使环境更新。

界面

该界面只是重载了switch-name参数,无论它们在何处出现,都允许使用目录名。例如

cd ~/src/project
opam switch create ./

将在~/src/project目录中创建一个本地切换。然后,例如,它等同于从该目录运行opam list,或者从任何位置运行opam list --switch=~/src/project

请注意,如果需要,您可以通过使用--switch参数,定义变量OPAMSWITCH或使用eval $(opam env --switch <name>)来绕过自动本地切换选择。

实现

实际上,切换内容放置在_opam/子目录中。因此,如果您创建了切换~/src/project,则可以在~/src/project/_opam中浏览其内容。这是切换的直接前缀,因此例如,可以在_opam/bin/中直接找到二进制文件:比搜索 opam 根目录更容易!opam 元数据放置在该目录下,位于.opam-switch/子目录中。

本地切换仍然共享 opam 根目录,特别是依赖于在其中定义和缓存的存储库。但是,现在可以为不同的切换选择不同的存储库,但这将是另一篇文章的主题。

最后,请注意,opam 会透明地处理删除该_opam目录,并且如果您希望在项目之间共享本地切换,则允许对_opam目录进行符号链接。

当前状态

此功能已在我们的开发版本中存在一段时间,您现在可以在当前测试版中使用它。

限制和未来扩展

目前,无法将本地切换目录移动,主要原因是与重新定位 OCaml 编译器相关的错误。

创建新的切换仍然需要重新编译所有包,甚至包括编译器本身(除非您依赖于系统安装)。预计的解决方案是添加一个构建缓存,避免需要使用相同的依赖项重新编译同一个包。这实际上应该可以使用当前的 opam 2.0 代码来完成,方法是利用新提供的钩子。请注意,重新定位 OCaml 也是一个问题,尽管如此。

ocp-indentmerlin这样的编辑工具也会因为切换的倍增而变得很烦人,因为如果它们没有安装在当前切换中,它们不会被自动找到。但是,user-setup插件(运行opam user-setup install)已经很好地处理了这个问题,并且如果在当前切换中找不到ocp-indenttuareg,它将从其初始切换中访问它们。但是,您仍然需要在需要它们的切换中安装与编译器版本紧密绑定的工具,例如merlinocp-index

注意:本文在opam.ocaml.orgocamlpro.com上交叉发布。请前往后者进行评论!