本地回购协议中的RStudio Connect、Packrat和定制软件包

本地回购协议中的RStudio Connect、Packrat和定制软件包,r,package,local,shiny-server,packrat,R,Package,Local,Shiny Server,Packrat,我们最近在我的办公室安装了RStudio Connect。对于我们的工作,我们制作了定制包,我们通过打开项目和构建+重新加载来更新这些包 我知道让我们的定制软件包在使用RSConnect的应用程序中工作的唯一方法是建立本地回购协议,并将我们的选项(回购协议)设置为包含此内容 目前我有以下几点: library(drat) RepoAddress <- "C:/<RepoPath>" # High level path drat::insertPackage(<sour

我们最近在我的办公室安装了RStudio Connect。对于我们的工作,我们制作了定制包,我们通过打开项目和构建+重新加载来更新这些包

我知道让我们的定制软件包在使用RSConnect的应用程序中工作的唯一方法是建立本地回购协议,并将我们的
选项(回购协议)
设置为包含此内容

目前我有以下几点:

library(drat)

RepoAddress <- "C:/<RepoPath>" # High level path

drat::insertPackage(<sourcePackagePath>, repodir = RepoAddress)

# Add this new repo to Rs knowledge of repos.
options(repos = c(options("repos")$repos,LocalCurrent = paste0("file:",RepoAddress)))

# Install <PackageName> from the local repo :)
install.packages("<PackageName>")

我知道这是一个问题,
packrat
在部署过程中找不到我的本地repo(我相信在它使用
packrat::snapshot()
)的阶段)。这让人困惑,因为我本以为
packrat
会使用我的
选项(“repo”)
repo类似于
install.packages
。如果我遵循这些函数,我可以看到特定的失败点是
packrat:::findLocalRepoForPkg(“问题在于术语

我已经建立了一个CRAN意义上的回购协议。它工作正常。当
packrat
引用
本地回购协议时,它是指本地git风格的回购协议


这就解决了为什么findlocalrepoforpkg看起来不起作用的问题——它被设计成与另一种回购协议一起工作。

请随时联系support@rstudio.com

我相信本地包代码路径是在packrat中触发的,因为包的描述文件中缺少
Repository:value
行。您提到您添加了这一行,您可以尝试区分大小写的版本吗


也就是说,RStudio Connect将无法按照您的指定从
RepoAddress
安装软件包(在Windows共享上硬编码)。我们建议通过https从您的开发环境和RStudio Connect都可以访问的服务器托管您的repo。为了使这种类型的repo设置更容易,我们刚刚发布了您(和它!)除了通过drat手动管理内部软件包的版本外,您可能会找到一个引人注目的替代方案。

您应该始终检查RStudio connect目前支持哪些选项:

就我个人而言,我不喜欢包括本地/私有软件包的所有选项,因为这会破坏部署闪亮应用程序的简单目标。在许多情况下,我不能只在组织中设置本地存储库,因为我没有权限这样做。还不方便的是,我必须通过电子邮件发送it支持来手动创建它们安装新的软件包。总的来说,我认为RS connect是一个很棒的产品,因为它很简单,但说到本地软件包,它就不是了

我找到了一个很好的替代方案/破解Rstudio官方推荐。我想这也适用于shinyapps.io,但我没有尝试。解决方案如下:

  • 如果(!require(local_package))devtools::load_all(“./local_package”),则添加到global.R

  • 编写一个复制所有源文件的脚本,这样您就可以得到一个shinyapp,其中包含本地包的源目录,您可以调用
    /inst/shinyconnect/
    的目录,或者将本地包复制到
    /inst/shinyconnect/local\u包
    舱单

  • 将script
    /shinyconnect/packrat\u查看这些依赖项。R
    添加到shiny文件夹,这将由packrat清单获取

  • 黑客rsconnet/packrat在构建时忽略特定命名的包

  • (1)

    (3) 使脚本加载本地包的所有依赖项。Packrat将看到这一点。脚本将永远不会实际执行。将其放置在
    /shinyconnect/Packrat\u查看这些依赖项。R

    #these codelines will be recognized by packrat and package will be added to manifest
    library(randomForest)
    library(MASS)
    library(whateverpackageyouneed)
    
    (4)在部署期间,清单生成器(packrat)将忽略任何命名的本地_包的存在。这是packrat中的一个选项,但rsconnect不公开此选项。一种黑客行为是将rsconnect加载到内存并修改子函数
    PerformPackageSnapshot()
    允许这样做。在下面的脚本中,我这样做并部署了一个闪亮的应用程序

    library(rsconnect)
    
    
    orig_fun = getFromNamespace("performPackratSnapshot", pos="package:rsconnect")
    
    #packages you want include manually, and packrat to ignore
    ignored_packages = c("local_package")
    
    #highjack rsconnect
    local({
      assignInNamespace("performPackratSnapshot",value =  function (bundleDir) {
          owd <- getwd()
          on.exit(setwd(owd), add = TRUE)
          setwd(bundleDir)
          srp <- packrat::opts$snapshot.recommended.packages()
          packrat::opts$snapshot.recommended.packages(TRUE, persist = FALSE)
          packrat::opts$ignored.packages(get("ignored_packages",envir = .GlobalEnv)) #ignoreing packages mentioned here
          print("ignoring following packages")
          print(get("ignored_packages",envir = .GlobalEnv))
          on.exit(packrat::opts$snapshot.recommended.packages(srp,persist = FALSE), add = TRUE)
          packages <- c("BiocManager", "BiocInstaller")
          for (package in packages) {
            if (length(find.package(package, quiet = TRUE))) {
              requireNamespace(package, quietly = TRUE)
              break
            }
          }
          suppressMessages(packrat::.snapshotImpl(project = bundleDir,
                                                  snapshot.sources = FALSE, fallback.ok = TRUE, verbose = FALSE,
                                                  implicit.packrat.dependency = FALSE))
          TRUE
        },
        pos = "package:rsconnect"
      )},
    envir = as.environment("package:rsconnect")
    )
    
    
    new_fun = getFromNamespace("performPackratSnapshot", pos="package:rsconnect")
    rsconnect::deployApp(appDir="./inst/shinyconnect/",appName ="shinyapp_name",logLevel = "verbose",forceUpdate = TRUE)
    
    库(rsconnect)
    orig_fun=getFromNamespace(“PerformPackageSnapshot”,pos=“package:rsconnect”)
    #您希望手动包含的包和忽略的packrat
    忽略的_包=c(“本地_包”)
    #highjack rsconnect
    本地的({
    assignInNamespace(“PerformPackageSnapshot”,值=函数(bundleDir){
    
    owd Hi Sean!您已经强调了我为自己创建的两个问题!第一个是我指的是我的C驱动器-我现在使用它的服务器路径将其更改为我们的网络驱动器。第二个部分是我使用了
    repository:value
    而不是
    repository:value
    。我现在遇到了一个错误,这意味着我需要我想我的RSConnect服务器能够看到我的网络驱动器,我想它会工作的。
    #these codelines will be recognized by packrat and package will be added to manifest
    library(randomForest)
    library(MASS)
    library(whateverpackageyouneed)
    
    library(rsconnect)
    
    
    orig_fun = getFromNamespace("performPackratSnapshot", pos="package:rsconnect")
    
    #packages you want include manually, and packrat to ignore
    ignored_packages = c("local_package")
    
    #highjack rsconnect
    local({
      assignInNamespace("performPackratSnapshot",value =  function (bundleDir) {
          owd <- getwd()
          on.exit(setwd(owd), add = TRUE)
          setwd(bundleDir)
          srp <- packrat::opts$snapshot.recommended.packages()
          packrat::opts$snapshot.recommended.packages(TRUE, persist = FALSE)
          packrat::opts$ignored.packages(get("ignored_packages",envir = .GlobalEnv)) #ignoreing packages mentioned here
          print("ignoring following packages")
          print(get("ignored_packages",envir = .GlobalEnv))
          on.exit(packrat::opts$snapshot.recommended.packages(srp,persist = FALSE), add = TRUE)
          packages <- c("BiocManager", "BiocInstaller")
          for (package in packages) {
            if (length(find.package(package, quiet = TRUE))) {
              requireNamespace(package, quietly = TRUE)
              break
            }
          }
          suppressMessages(packrat::.snapshotImpl(project = bundleDir,
                                                  snapshot.sources = FALSE, fallback.ok = TRUE, verbose = FALSE,
                                                  implicit.packrat.dependency = FALSE))
          TRUE
        },
        pos = "package:rsconnect"
      )},
    envir = as.environment("package:rsconnect")
    )
    
    
    new_fun = getFromNamespace("performPackratSnapshot", pos="package:rsconnect")
    rsconnect::deployApp(appDir="./inst/shinyconnect/",appName ="shinyapp_name",logLevel = "verbose",forceUpdate = TRUE)