diff --git a/DESCRIPTION b/DESCRIPTION index 14a8a95f..396a3902 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,4 +22,4 @@ Suggests: Enhances: BiocInstaller URL: https://github.com/rstudio/packrat/ BugReports: https://github.com/rstudio/packrat/issues -RoxygenNote: 5.0.1 +RoxygenNote: 6.0.1 diff --git a/R/aaa-globals.R b/R/aaa-globals.R index ce7fc884..a4826af7 100644 --- a/R/aaa-globals.R +++ b/R/aaa-globals.R @@ -37,5 +37,6 @@ new_defaults = function(value = list()) { ## These should be set on entering, exiting packrat mode .packrat_mutables <- new_defaults(list( origLibPaths = NULL, - project = NULL + project = NULL, + read.only = FALSE )) diff --git a/R/options.R b/R/options.R index 3fa34144..e92d0d53 100644 --- a/R/options.R +++ b/R/options.R @@ -22,7 +22,8 @@ VALID_OPTIONS <- list( snapshot.recommended.packages = list(TRUE, FALSE), snapshot.fields = function(x) { is.null(x) || is.character(x) - } + }, + read.only = list(TRUE, FALSE) ) default_opts <- function() { @@ -38,7 +39,8 @@ default_opts <- function() { ignored.packages = NULL, quiet.package.installation = TRUE, snapshot.recommended.packages = FALSE, - snapshot.fields = c("Imports", "Depends", "LinkingTo") + snapshot.fields = c("Imports", "Depends", "LinkingTo"), + read.only = FALSE ) } diff --git a/R/packrat-mode.R b/R/packrat-mode.R index fae2be08..7f10aaa7 100644 --- a/R/packrat-mode.R +++ b/R/packrat-mode.R @@ -2,8 +2,22 @@ isPackratModeOn <- function(project = NULL) { !is.na(Sys.getenv("R_PACKRAT_MODE", unset = NA)) } -setPackratModeEnvironmentVar <- function() { +# Check if packrat is in readonly mode +# If state is TRUE, will use packrat state, if it's FALSE will use variable environnement +isReadOnly <- function(state=TRUE) { + #mutables <- get(".packrat_mutables", envir = asNamespace("packrat")) + if(state){ + state <- .packrat_mutables$get() + return(state$read.only) + } + else{ + return(Sys.getenv("R_PACKRAT_READONLY_MODE") == "1") + } +} + +setPackratModeEnvironmentVar <- function(read.only=get_opts("read.only")) { Sys.setenv("R_PACKRAT_MODE" = "1") + Sys.setenv("R_PACKRAT_READONLY_MODE" = if(read.only) "1" else "0") } ensurePkgTypeNotBoth <- function() { @@ -13,7 +27,7 @@ ensurePkgTypeNotBoth <- function() { oldPkgType } -beforePackratModeOn <- function(project) { +beforePackratModeOn <- function(project, read.only=get_opts("read.only")) { # Ensure that we leave packrat mode before transfering # to a new project. @@ -39,11 +53,13 @@ beforePackratModeOn <- function(project) { .Library = .Library, .Library.site = .Library.site, project = project, - oldPkgType = oldPkgType + oldPkgType = oldPkgType, + read.only = read.only ) } else { state <- .packrat_mutables$get() state$project <- project + state$read.only <- read.only } state @@ -59,60 +75,64 @@ afterPackratModeOn <- function(project, project <- getProjectDir(project) libRoot <- libraryRootDir(project) localLib <- libDir(project) - dir.create(libRoot, recursive = TRUE, showWarnings = FALSE) - # Override auto.snapshot if running under RStudio, as it has its own packrat - # file handlers - if (!is.na(Sys.getenv("RSTUDIO", unset = NA))) { - auto.snapshot <- FALSE - } + if(!isReadOnly(state=FALSE)) + { + dir.create(libRoot, recursive = TRUE, showWarnings = FALSE) - # If snapshot.lock exists, assume it's an orphan of an earlier, crashed - # R process -- remove it - if (file.exists(snapshotLockFilePath(project))) { - unlink(snapshotLockFilePath(project)) - } + # Override auto.snapshot if running under RStudio, as it has its own packrat + # file handlers + if (!is.na(Sys.getenv("RSTUDIO", unset = NA))) { + auto.snapshot <- FALSE + } + + # If snapshot.lock exists, assume it's an orphan of an earlier, crashed + # R process -- remove it + if (file.exists(snapshotLockFilePath(project))) { + unlink(snapshotLockFilePath(project)) + } - # If there's a new library (created to make changes to packages loaded in the - # last R session), remove the old library and replace it with the new one. - newLibRoot <- newLibraryDir(project) - if (file.exists(newLibRoot)) { - message("Applying Packrat library updates ... ", appendLF = FALSE) - succeeded <- FALSE - if (file.rename(libRoot, oldLibraryDir(project))) { - if (file.rename(newLibRoot, libRoot)) { - succeeded <- TRUE + # If there's a new library (created to make changes to packages loaded in the + # last R session), remove the old library and replace it with the new one. + newLibRoot <- newLibraryDir(project) + if (file.exists(newLibRoot)) { + message("Applying Packrat library updates ... ", appendLF = FALSE) + succeeded <- FALSE + if (file.rename(libRoot, oldLibraryDir(project))) { + if (file.rename(newLibRoot, libRoot)) { + succeeded <- TRUE + } else { + # Moved the old library out of the way but couldn't move the new + # in its place; move the old library back + file.rename(oldLibraryDir(project), libRoot) + } + } + if (succeeded) { + message("OK") } else { - # Moved the old library out of the way but couldn't move the new - # in its place; move the old library back - file.rename(oldLibraryDir(project), libRoot) + message("FAILED") + cat("Packrat was not able to make changes to its local library at\n", + localLib, ". Check this directory's permissions and run\n", + "packrat::restore() to try again.\n", sep = "") } } - if (succeeded) { - message("OK") - } else { - message("FAILED") - cat("Packrat was not able to make changes to its local library at\n", - localLib, ". Check this directory's permissions and run\n", - "packrat::restore() to try again.\n", sep = "") - } - } - # If the new library temporary folder exists, remove it now so we don't - # attempt to reapply the same failed changes - newLibDir <- newLibraryDir(project) - if (file.exists(newLibDir)) { - unlink(newLibDir, recursive = TRUE) - } + # If the new library temporary folder exists, remove it now so we don't + # attempt to reapply the same failed changes + newLibDir <- newLibraryDir(project) + if (file.exists(newLibDir)) { + unlink(newLibDir, recursive = TRUE) + } - oldLibDir <- oldLibraryDir(project) - if (file.exists(oldLibDir)) { - unlink(oldLibDir, recursive = TRUE) - } + oldLibDir <- oldLibraryDir(project) + if (file.exists(oldLibDir)) { + unlink(oldLibDir, recursive = TRUE) + } - # If the library directory doesn't exist, create it - if (!file.exists(localLib)) { - dir.create(localLib, recursive = TRUE) + # If the library directory doesn't exist, create it + if (!file.exists(localLib)) { + dir.create(localLib, recursive = TRUE) + } } # Clean the search path up -- unload libraries that may have been loaded before @@ -128,8 +148,10 @@ afterPackratModeOn <- function(project, useSymlinkedSystemLibrary(project = project) } - # Refresh the contents of 'lib-ext' if necessary - symlinkExternalPackages(project = project) + if(!isReadOnly(state=FALSE)){ + # Refresh the contents of 'lib-ext' if necessary + symlinkExternalPackages(project = project) + } # Set the library if (!file.exists(libExtDir(project))) @@ -137,7 +159,8 @@ afterPackratModeOn <- function(project, setLibPaths(c(localLib, libExtDir(project))) # Load any packages specified in external.packages - if (isTRUE(opts$load.external.packages.on.startup())) { + # Don't load external packages in read.only mode as the we don't own the packrat, is not sure that we can access to external package + if (isTRUE(opts$load.external.packages.on.startup()) && isFALSE(isReadOnly(state=FALSE))) { lapply(opts$external.packages(), function(x) { library(x, character.only = TRUE, quietly = TRUE) }) @@ -165,12 +188,15 @@ afterPackratModeOn <- function(project, message(msg) } - # Insert hooks to library modifying functions to auto.snapshot on change - if (interactive() && isTRUE(auto.snapshot)) { - if (file.exists(getPackratDir(project))) { - addTaskCallback(snapshotHook, name = "packrat.snapshotHook") - } else { - warning("this project has not been packified; cannot activate automatic snapshotting") + if(!isReadOnly(state=FALSE)) + { + # Insert hooks to library modifying functions to auto.snapshot on change + if (interactive() && isTRUE(auto.snapshot)) { + if (file.exists(getPackratDir(project))) { + addTaskCallback(snapshotHook, name = "packrat.snapshotHook") + } else { + warning("this project has not been packified; cannot activate automatic snapshotting") + } } } @@ -206,20 +232,23 @@ afterPackratModeOn <- function(project, } } - # Update settings - updateSettings(project = project) - + if(!isReadOnly(state=FALSE)) + { + # Update settings + updateSettings(project = project) + } invisible(getLibPaths()) } setPackratModeOn <- function(project = NULL, + read.only = get_opts("read.only"), auto.snapshot = get_opts("auto.snapshot"), clean.search.path = TRUE, print.banner = TRUE) { - state <- beforePackratModeOn(project = project) - setPackratModeEnvironmentVar() + state <- beforePackratModeOn(project = project, read.only=read.only) + setPackratModeEnvironmentVar(read.only=read.only) afterPackratModeOn(project = project, auto.snapshot = auto.snapshot, clean.search.path = clean.search.path, @@ -238,9 +267,12 @@ setPackratModeOff <- function(project = NULL, } Sys.unsetenv("R_PACKRAT_MODE") + Sys.unsetenv("R_PACKRAT_READONLY_MODE") - # Disable hooks that were turned on before - removeTaskCallback("packrat.snapshotHook") + if(!isReadOnly()){ + # Disable hooks that were turned on before + removeTaskCallback("packrat.snapshotHook") + } # Reset the library paths libPaths <- .packrat_mutables$get("origLibPaths") @@ -267,8 +299,8 @@ setPackratModeOff <- function(project = NULL, # Default back to the current working directory for packrat function calls .packrat_mutables$set(project = NULL) + .packrat_mutables$set(read.only = FALSE) Sys.unsetenv("R_PACKRAT_PROJECT_DIR") - invisible(getLibPaths()) } @@ -295,6 +327,7 @@ checkPackified <- function(project = NULL, quiet = FALSE) { ##' will be toggled. ##' @param project The directory in which packrat mode is launched -- this is ##' where local libraries will be used and updated. +##' @param read.only Specfy that you want to use packrat in readonly mode (no modification can be done to the packrat in this mode) ##' @param auto.snapshot Perform automatic, asynchronous snapshots? ##' @param clean.search.path Detach and unload any packages loaded from non-system ##' libraries before entering packrat mode? @@ -306,6 +339,7 @@ checkPackified <- function(project = NULL, quiet = FALSE) { ##' @export packrat_mode <- function(on = NULL, project = NULL, + read.only = FALSE, auto.snapshot = get_opts("auto.snapshot"), clean.search.path = TRUE) { @@ -317,6 +351,7 @@ packrat_mode <- function(on = NULL, clean.search.path = clean.search.path) } else if (identical(on, TRUE)) { setPackratModeOn(project = project, + read.only = read.only, auto.snapshot = auto.snapshot, clean.search.path = clean.search.path) } else if (identical(on, FALSE)) { @@ -331,6 +366,7 @@ packrat_mode <- function(on = NULL, ##' @name packrat-mode ##' @export on <- function(project = NULL, + read.only = FALSE, auto.snapshot = get_opts("auto.snapshot"), clean.search.path = TRUE, print.banner = TRUE) { @@ -338,10 +374,15 @@ on <- function(project = NULL, project <- getProjectDir(project) # If there is no lockfile already, perform an init - if (!file.exists(lockFilePath(project = project))) - return(init(project = project)) + if (!file.exists(lockFilePath(project = project))) { + if(read.only) + stop("You must specified a valid packrat path, I dont't find it in '", project, "'!") + else + return(init(project = project)) + } setPackratModeOn(project = project, + read.only = read.only, auto.snapshot = auto.snapshot, clean.search.path = clean.search.path, print.banner = print.banner) diff --git a/R/utils.R b/R/utils.R index 466dc357..5aeabffa 100644 --- a/R/utils.R +++ b/R/utils.R @@ -216,6 +216,9 @@ stopIfNotPackified <- function(project) { call. = FALSE) } } + else if (isReadOnly() || isReadOnly(state = FALSE)) { + stop("Packrat is in readonly mode!", call. = FALSE) + } } # Expected to be used with .Rbuildignore, .Rinstignore diff --git a/man/appDependencies.Rd b/man/appDependencies.Rd index 3f01180a..619fed40 100644 --- a/man/appDependencies.Rd +++ b/man/appDependencies.Rd @@ -46,4 +46,3 @@ appDependencies("~/projects/shiny/app1") } } \keyword{internal} - diff --git a/man/bundle.Rd b/man/bundle.Rd index 75069c6f..f962ca08 100644 --- a/man/bundle.Rd +++ b/man/bundle.Rd @@ -47,4 +47,3 @@ be unbundled either with \code{packrat::\link{unbundle}} (which restores the project as well), \R's own \code{utils::\link{untar}}, or through most system \code{tar} implementations. } - diff --git a/man/clean.Rd b/man/clean.Rd index 36cf6e02..2bc436a4 100644 --- a/man/clean.Rd +++ b/man/clean.Rd @@ -40,4 +40,3 @@ clean("foo") } } - diff --git a/man/disable.Rd b/man/disable.Rd index c4a7606c..2769aa1c 100644 --- a/man/disable.Rd +++ b/man/disable.Rd @@ -29,4 +29,3 @@ The \code{restart} parameter will only result in a restart of R when the R environment packrat is running within makes available a restart function via \code{getOption("restart")}. } - diff --git a/man/init.Rd b/man/init.Rd index 9be5d5c1..6b06a9ab 100644 --- a/man/init.Rd +++ b/man/init.Rd @@ -65,4 +65,3 @@ packrat::init(options = list(local.repos = "~/projects/R")) \link{packrat} for a description of the files created by \code{init}. } - diff --git a/man/install.Rd b/man/install.Rd index 79af76c0..dc7cf5a6 100644 --- a/man/install.Rd +++ b/man/install.Rd @@ -57,4 +57,3 @@ directory pristine. If the package is loaded, it will be reloaded after installation. } - diff --git a/man/install_local.Rd b/man/install_local.Rd index b20586f9..47b2423a 100644 --- a/man/install_local.Rd +++ b/man/install_local.Rd @@ -20,4 +20,3 @@ install_local(pkgs, ..., lib = .libPaths()[1], This function can be used to install a package from a local 'repository'; i.e., a directory containing package tarballs and sources. } - diff --git a/man/migrate.Rd b/man/migrate.Rd index a364ed56..9d60336b 100644 --- a/man/migrate.Rd +++ b/man/migrate.Rd @@ -26,4 +26,3 @@ This function will: \item Update the package \code{.Rprofile}. } } - diff --git a/man/packify.Rd b/man/packify.Rd index 4da6ca33..a515ba80 100644 --- a/man/packify.Rd +++ b/man/packify.Rd @@ -25,4 +25,3 @@ source control, or were accidentally removed). You'll need to restart \R in the specified directory after running \code{packify} in order to start using the private package library. } - diff --git a/man/packrat-external.Rd b/man/packrat-external.Rd index b3a42b32..85c2f571 100644 --- a/man/packrat-external.Rd +++ b/man/packrat-external.Rd @@ -1,11 +1,14 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/external.R, R/paths.R \name{packrat-external} +\alias{packrat-external} +\alias{with_extlib} +\alias{packrat-external} \alias{extlib} \alias{packrat-external} -\alias{packrat_lib} \alias{user_lib} -\alias{with_extlib} +\alias{packrat-external} +\alias{packrat_lib} \title{Managing External Libraries} \usage{ with_extlib(packages, expr, envir = parent.frame()) @@ -35,4 +38,3 @@ libraries; that is, the libraries that would be available upon launching a new with_extlib("lattice", xyplot(1 ~ 1)) } } - diff --git a/man/packrat-mode.Rd b/man/packrat-mode.Rd index bcc2e3ae..754e32f2 100644 --- a/man/packrat-mode.Rd +++ b/man/packrat-mode.Rd @@ -1,17 +1,20 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/packrat-mode.R \name{packrat-mode} -\alias{off} -\alias{on} \alias{packrat-mode} \alias{packrat_mode} +\alias{packrat-mode} +\alias{on} +\alias{packrat-mode} +\alias{off} \title{Packrat Mode} \usage{ -packrat_mode(on = NULL, project = NULL, +packrat_mode(on = NULL, project = NULL, read.only = FALSE, auto.snapshot = get_opts("auto.snapshot"), clean.search.path = TRUE) -on(project = NULL, auto.snapshot = get_opts("auto.snapshot"), - clean.search.path = TRUE, print.banner = TRUE) +on(project = NULL, read.only = FALSE, + auto.snapshot = get_opts("auto.snapshot"), clean.search.path = TRUE, + print.banner = TRUE) off(project = NULL, print.banner = TRUE) } @@ -22,6 +25,8 @@ will be toggled.} \item{project}{The directory in which packrat mode is launched -- this is where local libraries will be used and updated.} +\item{read.only}{Specfy that you want to use packrat in readonly mode (no modification can be done to the packrat in this mode)} + \item{auto.snapshot}{Perform automatic, asynchronous snapshots?} \item{clean.search.path}{Detach and unload any packages loaded from non-system @@ -36,4 +41,3 @@ Use these functions to switch \code{packrat} mode on and off. When within \code{packrat} mode, the \R session will use the private library generated for the current project. } - diff --git a/man/packrat-options.Rd b/man/packrat-options.Rd index d8410057..20464558 100644 --- a/man/packrat-options.Rd +++ b/man/packrat-options.Rd @@ -2,10 +2,11 @@ % Please edit documentation in R/options.R \docType{data} \name{packrat-options} +\alias{packrat-options} \alias{get_opts} -\alias{opts} \alias{packrat-options} \alias{set_opts} +\alias{opts} \title{Get/set packrat project options} \usage{ get_opts(options = NULL, simplify = TRUE, project = NULL) @@ -86,6 +87,7 @@ Get and set options for the current packrat-managed project. (character, defaults to \code{c("Imports", "Depends", "LinkingTo")}) } } + \examples{ \dontrun{ ## use 'devtools' and 'knitr' from the user library @@ -102,4 +104,3 @@ packrat::opts$external.packages(c("devtools", "knitr")) } } \keyword{datasets} - diff --git a/man/packrat-resources.Rd b/man/packrat-resources.Rd index d2969923..9b193389 100644 --- a/man/packrat-resources.Rd +++ b/man/packrat-resources.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/paths.R \name{packrat-resources} -\alias{bundles_dir} -\alias{lib_dir} \alias{packrat-resources} \alias{project_dir} \alias{src_dir} +\alias{lib_dir} +\alias{bundles_dir} \title{Paths to Packrat Resources} \usage{ project_dir(project = NULL) diff --git a/man/packrat.Rd b/man/packrat.Rd index 5979e059..144c4677 100644 --- a/man/packrat.Rd +++ b/man/packrat.Rd @@ -63,6 +63,7 @@ version control system. Be sure to check in the \code{.Rprofile}, feel free to check it in if you don't mind taking up some extra space in your repository). } + \examples{ \dontrun{ # Create a new packrat project from an existing directory of \\R code @@ -81,4 +82,3 @@ restore() \author{ RStudio, Inc. } - diff --git a/man/repos_create.Rd b/man/repos_create.Rd index 801c8882..916c1533 100644 --- a/man/repos_create.Rd +++ b/man/repos_create.Rd @@ -18,4 +18,3 @@ directory name in which the reopsitory is created.} Generate a local CRAN-like repository which can be used to store and distribute \R packages. } - diff --git a/man/repos_upload.Rd b/man/repos_upload.Rd index 9a425faf..997079f0 100644 --- a/man/repos_upload.Rd +++ b/man/repos_upload.Rd @@ -21,4 +21,3 @@ be a local (on-disk) CRAN repository.} \description{ Upload a Package to a Local CRAN-like Repository } - diff --git a/man/repository-management.Rd b/man/repository-management.Rd index b53f39b6..e96102c4 100644 --- a/man/repository-management.Rd +++ b/man/repository-management.Rd @@ -1,13 +1,18 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/cranlike-repositories.R \name{repository-management} +\alias{repository-management} \alias{repos_add} +\alias{repository-management} \alias{repos_add_local} -\alias{repos_list} -\alias{repos_remove} +\alias{repository-management} \alias{repos_set} +\alias{repository-management} \alias{repos_set_local} \alias{repository-management} +\alias{repos_remove} +\alias{repository-management} +\alias{repos_list} \title{Add a Repository} \usage{ repos_add(..., overwrite = FALSE) @@ -40,4 +45,3 @@ effectively an easier-to-use wrapper over interacting with the \code{repos_add_local} is used for adding file-based repositories; that is, CRAN repositories that live locally on disk and not on the internet / local network. } - diff --git a/man/restore.Rd b/man/restore.Rd index 38aca39c..f8cf7be8 100644 --- a/man/restore.Rd +++ b/man/restore.Rd @@ -75,4 +75,3 @@ via \code{getOption("restart")}. \code{\link{status}} to view the differences between the most recent snapshot and the library. } - diff --git a/man/search_path.Rd b/man/search_path.Rd index 352d51b3..e9029b9b 100644 --- a/man/search_path.Rd +++ b/man/search_path.Rd @@ -10,4 +10,3 @@ search_path() Retrieve the packages on the search path, as well as the associated library location. } - diff --git a/man/snapshot.Rd b/man/snapshot.Rd index b932104a..f027e26b 100644 --- a/man/snapshot.Rd +++ b/man/snapshot.Rd @@ -60,4 +60,3 @@ snapshot(dry.run = TRUE) \code{\link{status}} to view the differences between the most recent snapshot and the library. } - diff --git a/man/snapshotImpl.Rd b/man/snapshotImpl.Rd index 802b3cbd..77ed48d0 100644 --- a/man/snapshotImpl.Rd +++ b/man/snapshotImpl.Rd @@ -57,4 +57,3 @@ This is the internal implementation for \code{\link{snapshot}}. Most users should prefer calling \code{\link{snapshot}}. } \keyword{internal} - diff --git a/man/status.Rd b/man/status.Rd index ee633fc8..84cb7ae8 100644 --- a/man/status.Rd +++ b/man/status.Rd @@ -37,4 +37,3 @@ Differences can also arise if one of your collaborators adds or removes packages from the packrat dependencies. In this case, you simply need to tell packrat to update your private package library using \code{\link{restore}}. } - diff --git a/man/unbundle.Rd b/man/unbundle.Rd index b6bfce44..95ac5ca4 100644 --- a/man/unbundle.Rd +++ b/man/unbundle.Rd @@ -19,4 +19,3 @@ after \code{unbundle}-ing the project?} \description{ Unbundle a previously \code{\link{bundle}}d project. } - diff --git a/man/unused_packages.Rd b/man/unused_packages.Rd index 9c866fa3..22769664 100644 --- a/man/unused_packages.Rd +++ b/man/unused_packages.Rd @@ -15,4 +15,3 @@ unused_packages(project = NULL, lib.loc = libDir(project)) Unused packages are those still contained within your project library, but are unused in your project. } -