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-indent
或merlin
这样的编辑工具也会因为切换的倍增而变得很烦人,因为如果它们没有安装在当前切换中,它们不会被自动找到。但是,user-setup
插件(运行opam user-setup install
)已经很好地处理了这个问题,并且如果在当前切换中找不到ocp-indent
或tuareg
,它将从其初始切换中访问它们。但是,您仍然需要在需要它们的切换中安装与编译器版本紧密绑定的工具,例如merlin
和ocp-index
。
注意:本文在opam.ocaml.org和ocamlpro.com上交叉发布。请前往后者进行评论!