-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Respect renv lockfiles #791
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we renv->manifest rather than renv->packrat->manifest?
Consistent name for renv file
I'm still fighting some buglet with BioC packages. In a project that uses
The manifest looks ok to me:
I suspect there's some small mistake that will hopefully be obvious when I look at it on Monday. |
BioC install problem was caused by colorado only having 4.1 installed. Works on rstudioservices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I think this change makes sense, especially because packrat
is itself using a vendored version of renv
to snapshot dependencies.
It seems like a lot of the complexity here is within the blocks that standardize the different ways packrat
, renv
, and pak
record package metadata, as well as assumptions they make about packages that aren't just structural differences (and how these have evolved over time). I appreciate having links to the relevant source in the comments. (The one that stood out to me was the check for isDevVersion()
).
The Bitbucket name capitalization is the only required change I noticed. But I only noticed it because I spent long enough with Bitbucket when I was implementing support for restoring those packages in Connect. We'll probably want to do some real-world tire-kicking of those sorts of scenarios in case there are other small things like that we missed. Either that or build out more examples in tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some questions about package+repository handling, but this is probably far enough along to merge and get folks to start actively using it.
#' 2. Otherwise, rsconnect will call `renv::snapshot()` to find all packages | ||
#' used by your code. If you'd instead prefer to only use the packages | ||
#' declared in a `DESCRIPTION` file, run | ||
#' `renv::settings$snapshot.type("explicit")` to activate renv's "explicit" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think that folks will need an explicit snapshot type for deploys and another snapshot type for all other workflows? Put another way: Do we need a way to toggle the snapshot type just for deploys?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renv::snapshot()
does accept a type
argument so this would be straightforward to wire up, at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My sense is that once we enable support for renv lockfile, we'll get quite a few feature requests so we might as well just let them accumulate for a while to get a sense for what people actually want, rather than doing too much prospectively.
@@ -179,7 +179,7 @@ ignoreBundleFiles <- function(dir, contents) { | |||
# rsconnect packages | |||
"rsconnect", "rsconnect-python", "manifest.json", | |||
# packrat + renv, | |||
"renv", "renv.lock", "packrat", | |||
"renv", "packrat", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The renv/settings.json
isn't included; does this mean that a snapshot.type
set in a previous session will not be available?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but I don't think that should matter because the settings only really affect interactive usage, and the consequence of those settings will be encoded in the lockfile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The recommendation to use renv::settings$snapshot.type("explicit")
presents a challenge, then, if we expect folks to set that ahead of each deploy operation but do so in a way that does not modify their existing renv project settings. What is your suggested workflow?
packages_list <- lapply(seq_len(nrow(packages)), function(i) { | ||
out <- as.list(packages[i, , drop = FALSE]) | ||
# Manifest packages used to generate packrat file on Connect | ||
# https://github.com/rstudio/connect/blob/v2023.03.0/src/connect/manifest/convert.go#L261-L320 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This is an internal source reference.
@@ -179,7 +179,7 @@ ignoreBundleFiles <- function(dir, contents) { | |||
# rsconnect packages | |||
"rsconnect", "rsconnect-python", "manifest.json", | |||
# packrat + renv, | |||
"renv", "renv.lock", "packrat", | |||
"renv", "packrat", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this cause renv.lock
to be included in the bundle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; that's necessary so that we can process it in bundlePackages()
. Do you foresee a problem with including this in the deployed bundle? If so, I can delete. (But I think you could also renv::restore()
directly from that file without having to convert the manifest back into a packrat spec).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am torn on this one.
On the one hand, including only the manifest.json
in the bundle is quite nice because it means we have a single source-of-truth. Folks have been confused by the presence of both manifest.json
and packrat.lock
in our bundles, as well as the relationship between the two (and duplication of information).
On the other hand, I like including the renv.lock
, as it gives us a future option of directly using that file without reconstructing it from the manifest.
Mostly, my struggle is that I had thought about this change as "manifest-only, no packrat.lock" rather than "manifest plus renv.lock; except when we create the renv.lock on the fly".
Let's go forward with the (sometimes) inclusion, but probably document the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like it would be a bit more consistent to include lock file, even when we generate it? I'm currently explicitly deleting it, but it seems reasonable to remove that code and preserve the lock file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A generated lock file isn't on the set of "bundle files" that was computed much earlier in the workflow... I'm OK either way, but if we do include a generated lock file, let's include it only when we have tracked dependencies (e.g. not for static).
} else { | ||
# $Repository comes from DESCRIPTION and is set by repo, so can be | ||
# anything. So we must look up from the package name | ||
pkg$Repository <- findRepoUrl(pkg$Package, availablePackages) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: during restore, renv first favors a matching repository name before falling back to "any" repository. not sure if we want that same pattern here or want to rely available.packages
order like we do for Packrat.
Maybe this is: prefer the Repository named in renv.lock and prefer available.packages for snapshots.
Also worth considering: Should we prefer the renv.lock repository list or the list in the current R session?
https://github.com/rstudio/renv/blob/81fecb07fcc78cabb61b5309875e59484727b090/R/retrieve.R#L875-L880
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM!
DESCRIPTION
Outdated
@@ -28,13 +28,15 @@ Imports: | |||
lifecycle, | |||
openssl (>= 2.0.0), | |||
packrat (>= 0.6), | |||
renv, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if you need it for this PR, but if you'd like to depend on renv
internals without risking breakage from new renv
releases, you can also use renv::embed()
to embed a local copy of renv
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related thought: Do we need a version constraint on renv?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to embed because we're only using exported functions so far, but will keep it in mind for the future.
I've add a requirement for the latest version from CRAN.
#' 2. Otherwise, rsconnect will call `renv::snapshot()` to find all packages | ||
#' used by your code. If you'd instead prefer to only use the packages | ||
#' declared in a `DESCRIPTION` file, run | ||
#' `renv::settings$snapshot.type("explicit")` to activate renv's "explicit" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renv::snapshot()
does accept a type
argument so this would be straightforward to wire up, at least.
local_version <- record$Version | ||
repo_version <- availablePackages[record$Package, "Version"] | ||
|
||
package_version(local_version) > package_version(repo_version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also detect whether the trailing version component is "large"? In case a local version is 1.0.0-9000 but CRAN has 1.0.1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not a version used by every package, so I worry that would dilute the impact of this change.
Co-authored-by: Toph Allen <[email protected]>
Co-authored-by: Kevin Ushey <[email protected]>
Co-authored-by: Toph Allen <[email protected]>
Co-authored-by: Toph Allen <[email protected]>
#Conflicts: # NEWS.md
I think this is done, and I've finally managed to knock of the CI failure. Unless anyone spots any problems, I'll aim to merge tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looked through the changes since my last review, and they all look good.
@aronatkins and @kevinushey: this is still an early draft, but I thought it would be useful to get some feedback now that I've put a couple of hours into it. It still needs a bunch of testing, and I doubt i have all the details of the renv -> packrat translation are fully correct yet, but this overall this feels like a solid approach to me. What do you think?
Fixes #671. Fixes #809.