rstudio / rsconnect

Publish Shiny Applications, RMarkdown Documents, Jupyter Notebooks, Plumber APIs, and more
http://rstudio.github.io/rsconnect/
131 stars 80 forks source link

deployement of packrat managed application #227

Closed cderv closed 1 year ago

cderv commented 6 years ago

Hi,

I try to understand how I could deploy to RStudio Connect a project with dependencies managament using packrat. If you have advice, feel free to share ! I open this issue to share my understanding and some strange behaviour.

Without packrat, during deployement with rsconnect, it will be the system and user library that will act as reference for package snapshot version. It is fine in some case but for other I want to have dependencies with the project and I use a packrat project for that.

I have a packrat folder, and I activate packrat before deployment so that project's libraries are taken into account. At the end, I manage to publish it, but it does not seem to be working properly. here is my insights.

When I click on publish button in RStudio IDE, it does not allow me to add pakrat.lock file in the bundle. I said myself it should work another way as rsconnect uses packrat itself in the process. However, rsconnect does not find all my packages into my packrat library folder but some are used inside my global installation instead. My application is then deployed with the wrong package version dependencies - should be my packrat deps not my global package.

the getPackageRecordsExternalSource function use system.file to find the path of description. It happens, after investigation, that if I have for some reason a package loaded in namespaces, that does not come from my packrat lib, this will be this global paths which comes first and take over the path of package in .libPaths(). that is the way find.package is working; This case happens when I use an external package with packrat::with_extlib that loads a package from global lib for some reason even if it is present in packrat lib.

getPackageRecordsExternalSource function ```r getPackageRecordsExternalSource <- function(pkgNames, available, lib.loc, missing.package, fallback.ok = FALSE) { lapply(pkgNames, function(pkgName) { # The actual package record that will be populated by below logic. result <- list() # First, attempt to discover the actual installation for this package. pkgDescFile <- system.file("DESCRIPTION", package = pkgName, lib.loc = lib.loc) if (file.exists(pkgDescFile)) { # If the package is currently installed, then we can return a package # record constructed from the DESCRIPTION file. df <- as.data.frame(readDcf(pkgDescFile)) result <- suppressWarnings(inferPackageRecord(df)) ```

I have to be very careful about what I am doing before deploying and I have to check if everything ok. Not easy. After that, it took me a while to understand that I can put my `packrat.lock` file in the bundle. (obviously using `deployApp` only as I cannot select this file from publish menu). Digging into the code, I saw that if I put this file in the bundle, it should look for dependencies inside it and no more try to find package using `system.file` and `find.package`. It prevents from previous situation ! great !
inferredPkgRecords has check.lockfile = TRUE [code](https://github.com/rstudio/packrat/blob/df5dd5b6cb9f72010e07ccd3f4f813ab036d42c2/R/snapshot.R#L197) ```r # For inferred packages (ie. packages within the code), we try to construct # records first from the lockfile, and then from other sources if possible # (CRAN, GitHub, source repository) inferredPkgRecords <- getPackageRecords(inferredPkgsNotInLib, project = project, available = available, check.lockfile = TRUE, fallback.ok = fallback.ok) ```

With this, the lockfile inside the rsconnect bundleapp is ok. However, when creating a copy of the desc files in the bundle, it looks for `DESCRIPTION` file with `system.file` and I have the same issue as my first observation. https://github.com/rstudio/rsconnect/blob/a16b8485ee4c7d43842bf13ebed2d312410f2285/R/bundle.R#L557-L565 That is to say the bundle pushed to rstudio connect, has a correct lockfile and then has correct packages version installed but the desc folder does not contains the correct package version and info because it copied it from the wrong path found by `system.file`. I was expecting that the current desc folder in packrat dir was used for copy DESCRIPTION file. Not sure what these desc folder is used for but it does not look ok to me. In conclusion, there is something strange in what I am doing or in current `packrat` behavior. I have this use case of packrat managed app deployement, either when I want to publish a locally `packrat` managed app, or when I download a bundle for RStudio Connect, restore using the packrat.lock in the bundle, and want to push on another server with same dependencies. (in the download bundle, `desc` folder has incorrect file by the way, as I mentionned earlier.) Have you encountered such things ? What are the correct workflow to push packrat managed project using `rsconnect` ? _(If I manage to create a reproductible project, I will add this to show the different behavior)_
trestletech commented 6 years ago

Hi! I'm unfortunately not the best person to be able to answer this as I'm still struggling to get my head around the question. But I did want to pass along these two links in case either prove helpful:

Here's a repo that demonstrates publishing to RSC from a continuous integration system (which involves recreating the Packrat environment from a git repo). https://github.com/slopp/rsc-ci-test

Some of the packrat/Travis code in that repo comes from https://rstudio.github.io/shinytest/articles/ci.html, which may also be a helpful resource.

hadley commented 1 year ago

Now tracking the equivalent in #471