我目前使用renv
进行实验,以确保我的所有同事在开发过程中使用相同版本的软件包。然而,有一件事我到目前为止还不知道该怎么做。
假设存在包a需要特定版本的exampleLibrary,设1.0.0. 这导致这个包的renv.lock
有这样的条目:
"exampleLibrary": {
"Package": "exampleLibrary",
"Version": "1.0.0",
"Source": "Repository",
"Repository": "GITLAB",
"Hash": "c0e49a9760983e81e55cdd9be92e7182",
"Requirements": []
}
现在,一段时间后,有人开发了另一个包B,并想使用包a中的一些实用程序,他称之为renv::install("package A")
。这将导致在包B的renv.lock
中出现上述代码片段的类似条目.
但是,如果发生以下情况:一段时间后,您忘记了包A依赖于exampleLibrary 1.0.0然后运行renv::install("exampleLibrary@2.0.0")
,因为你想升级exampleLibrary。这将替换renv.lock
中的条目,没有任何警告或错误。当包A时,这可能会导致大麻烦。不能使用exampleLibrary@2.0.0.
我希望renv对包的依赖关系进行如下编码:
"package A": {
"Package": "package A",
"Version": "1.0.0",
"Source": "Repository",
"Repository": "GITLAB",
"Hash": "c0e49a9760983e81e55cdd9be92e7182",
"Requirements": [exampleLibrary (==1.0.0)]
}
这种场景的另一个例子是,您安装了两个具有相同依赖关系但使用其他版本的包。后一个安装包的版本最终会在没有任何警告的情况下被取走。
有什么方法可以防止这种情况吗?
对不起,但你所描述的是不可能与renv
。renv
使用的模型是renv::snapshot()
保存R库的状态——不多也不少。在调用renv::snapshot()
之前,用户有责任验证库本身是否处于有效状态。
但是,如果发生以下情况:一段时间后,您忘记了软件包A依赖于exampleLibrary 1.0.0,并且您运行renv::install("exampleLibrary@2.0.0"),因为您想升级exampleLibrary。这将替换renv中的条目。在没有任何警告或错误的情况下锁定。当包A不能与exampleLibrary@2.0.0一起工作时,这可能会导致大麻烦。
renv::install()
只会更新renv.lock
,如果您已经启用了自动快照—参见https://rstudio.github.io/renv/reference/config.html#renv-config-auto-snapshot了解详细信息。默认情况下,这是关闭的,因此您需要在安装或更新一些包后显式调用renv::snapshot()
,以便将这些记录在lockfile中。
这种场景的另一个例子是,您安装了两个具有相同依赖关系但使用其他版本的软件包。后一个安装包的版本最终会在没有任何警告的情况下被取走。
注意,R通常不支持同一包的多个版本同时安装或加载——你必须选择一个特定的版本。这就是为什么renv
没有尝试将特定的包版本编码为包的需求的部分原因,因为人们会很快发现无法解决的冲突。