From 262a2423d2b3ed072ace32f5ac65fbc3cc6e612e Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Fri, 28 Jun 2024 14:34:01 +0200 Subject: [PATCH 01/21] rix_init_after_rix --- R/rix.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/rix.R b/R/rix.R index eb07f58f..b32eac32 100644 --- a/R/rix.R +++ b/R/rix.R @@ -262,6 +262,9 @@ for more details." if (!file.exists(project_path) || overwrite) { writeLines(default.nix, project_path) + rix_init(project_path = project_path, + rprofile_action = "append", + message_type = "simple", "quiet", "verbose") } else { stop(paste0("File exists at ", project_path, ". Set `overwrite == TRUE` to overwrite.")) } From 2f8c143d18fc89a4526597f40a48b51476714488 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Fri, 28 Jun 2024 15:00:04 +0200 Subject: [PATCH 02/21] better warning if default.nix exists already --- R/rix.R | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/R/rix.R b/R/rix.R index b32eac32..2552fa9a 100644 --- a/R/rix.R +++ b/R/rix.R @@ -176,7 +176,7 @@ for more details." ) } - project_path <- if (project_path == ".") { + default.nix_path <- if (project_path == ".") { "default.nix" } else { paste0(project_path, "/default.nix") @@ -187,7 +187,7 @@ for more details." # fork is used. Otherwise, upstream NixOS/nixpkgs nix_repo <- make_nixpkgs_url(r_ver) - project_path <- file.path(project_path) + default.nix_path <- file.path(default.nix_path) rix_call <- match.call() @@ -260,12 +260,17 @@ for more details." cat(default.nix, sep = "\n") } - if (!file.exists(project_path) || overwrite) { - writeLines(default.nix, project_path) + if (!file.exists(default.nix_path) || overwrite) { + writeLines(default.nix, default.nix_path) rix_init(project_path = project_path, - rprofile_action = "append", - message_type = "simple", "quiet", "verbose") + rprofile_action = "create_missing", + message_type = "quiet") } else { - stop(paste0("File exists at ", project_path, ". Set `overwrite == TRUE` to overwrite.")) + project_path <- if(project_path == ".") { + "current folder" + } else { + project_path + } + stop(paste0("default.nix exists in ", project_path, ". Set `overwrite == TRUE` to overwrite.")) } } From a23b4331a50973988b8bac6a6c4ff219463c65b1 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Fri, 28 Jun 2024 21:09:08 +0200 Subject: [PATCH 03/21] shimed install.packages() --- R/rix_init.R | 3 +++ tests/testthat/_snaps/rix_init/golden_Rprofile.txt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/R/rix_init.R b/R/rix_init.R index 7e097579..9fbd057a 100644 --- a/R/rix_init.R +++ b/R/rix_init.R @@ -412,6 +412,9 @@ nix_rprofile <- function() { } if (isTRUE(is_nix_r)) { + install.packages <- function(...){ + stop("You are currently in an R session running from Nix.\nDon't install packages using install.packages(),\nadd them to the default.nix file instead.") + } current_paths <- .libPaths() userlib_paths <- Sys.getenv("R_LIBS_USER") user_dir <- grep(paste(userlib_paths, collapse = "|"), current_paths, fixed = TRUE) diff --git a/tests/testthat/_snaps/rix_init/golden_Rprofile.txt b/tests/testthat/_snaps/rix_init/golden_Rprofile.txt index 4bc3ad05..6e58b31a 100644 --- a/tests/testthat/_snaps/rix_init/golden_Rprofile.txt +++ b/tests/testthat/_snaps/rix_init/golden_Rprofile.txt @@ -21,6 +21,9 @@ rm(old_path, nix_path) } if (isTRUE(is_nix_r)) { + install.packages <- function(...) { + stop("You are currently in an R session running from Nix.\nDon't install packages using install.packages(),\nadd them to the default.nix file instead.") + } current_paths <- .libPaths() userlib_paths <- Sys.getenv("R_LIBS_USER") user_dir <- grep(paste(userlib_paths, collapse = "|"), current_paths, fixed = TRUE) From 00f6dfb7e8b907ab8fc67d9a671bed79f84de156 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Fri, 28 Jun 2024 21:49:08 +0200 Subject: [PATCH 04/21] Adapted documenattion --- R/rix.R | 5 + R/with_nix.R | 3 +- inst/extdata/default.nix | 4 +- vignettes/a-getting-started.Rmd | 8 +- .../b2-setting-up-and-using-rix-on-macos.Rmd | 32 ++----- ...to-build-project-specific-environments.Rmd | 21 +++- vignettes/e-interactive-use.Rmd | 55 +++++------ ...-running-r-or-shell-code-in-nix-from-r.Rmd | 96 ++++--------------- 8 files changed, 80 insertions(+), 144 deletions(-) diff --git a/R/rix.R b/R/rix.R index 2552fa9a..4a1acf86 100644 --- a/R/rix.R +++ b/R/rix.R @@ -176,6 +176,11 @@ for more details." ) } + if (isFALSE(dir.exists(project_path))) { + dir.create(path = project_path, recursive = TRUE) + project_path <- normalizePath(path = project_path) + } + default.nix_path <- if (project_path == ".") { "default.nix" } else { diff --git a/R/with_nix.R b/R/with_nix.R index 41a7bcaf..8a0bb7bd 100644 --- a/R/with_nix.R +++ b/R/with_nix.R @@ -38,12 +38,11 @@ #' can easily do so by providing Nix expressions in custom `.nix` or #' `default.nix` files in different subfolders of the project. #' -#' It is recommended that you use `rix_init()` to generate a custom `.Rprofile` +#' `rix_init()` is run automatically to generate a custom `.Rprofile` #' file for the subshell in `project_dir`. The defaults in that file ensure #' that only R packages from the Nix store, that are defined in the subshell #' `.nix` file are loaded and system's libraries are excluded. #' -#' #' To do its job, `with_nix()` heavily relies on patterns that manipulate #' language expressions (aka computing on the language) offered in base R as #' well as the \{codetools\} package by Luke Tierney. diff --git a/inst/extdata/default.nix b/inst/extdata/default.nix index 3fe848b6..76b70e90 100644 --- a/inst/extdata/default.nix +++ b/inst/extdata/default.nix @@ -23,8 +23,8 @@ let src = pkgs.fetchgit { url = "https://github.com/b-rodrigues/rix/"; branchName = "master"; - rev = "1a9680f892024ca08d2b5af737baba0a9a042339"; - sha256 = "sha256-HkNE+4VrtqEOOMxyxqz6jnSMg/1SOppdTyKif/yR0ss="; + rev = "9e3bdfa6c508a2a549aae9e41c14d2ead0a9191d"; + sha256 = "sha256-uYjCuH7z7enk6i0Kb2inErXdfDA2OkKei8jr3HvKNh0="; }; propagatedBuildInputs = builtins.attrValues { inherit (pkgs.rPackages) diff --git a/vignettes/a-getting-started.Rmd b/vignettes/a-getting-started.Rmd index 630d3942..1ec0a1c8 100644 --- a/vignettes/a-getting-started.Rmd +++ b/vignettes/a-getting-started.Rmd @@ -174,8 +174,12 @@ to a Nix environment while analyzing data, you need to add it the `default.nix` expression and rebuild the environment. This is explained in greater detail in `vignette("d1-installing-r-packages-in-a-nix-environment")`. -To avoid interference between your main R library of packages and your -Nix environments, we recommend you read the documentation of `rix_init()`. +To avoid interference between your main R library of packages and your Nix +environments, calling `rix()` will also run `rix_init()`, which will create a +custom `.Rprofile` in the project's directory. This `.Rprofile` will ensure that +if you have a user library of packages, these won't get loaded by an R version +running in a Nix shell. It will also redefine `install.packages()` to throw an +error if you try to use it. `rix()` has several arguments: diff --git a/vignettes/b2-setting-up-and-using-rix-on-macos.Rmd b/vignettes/b2-setting-up-and-using-rix-on-macos.Rmd index 044c09ac..d5b9237d 100644 --- a/vignettes/b2-setting-up-and-using-rix-on-macos.Rmd +++ b/vignettes/b2-setting-up-and-using-rix-on-macos.Rmd @@ -31,7 +31,6 @@ running Linux thanks to WSL2. In practice this means that Linux distributions and Windows can be considered one system, and macOS another, separate, system, with its own idiosyncrasies. This vignette details these. - ## Installing Nix You can use `{rix}` to generate Nix expressions even if you don't have Nix @@ -117,35 +116,21 @@ backwards-compatibility. ### Shared libraries issue -When using environments built with Nix on macOS, you might get crashes +When using environments built with Nix on macOS, you might get crashes (segmentation faults) refering to "shared libraries". These indicate that your user library of R packages is interfering with the project-specific Nix -environment. The system's user library that Nix packaged R by default includes +environment. The system's user library that Nix packaged R by default includes appears in the search paths (check `libPaths()`). For macOS, the user library is at `/Library/Frameworks/R.framework/Versions/.-/Resources/library`; we have observed crashes with R packages that depend on system libraries, such as {data.table} or {dplyr}, and their (reverse) dependencies. Because user -libraries from the system would also appear on the search path in R from -`nixpkgs` for Linux, we think its a good idea to force isolation of R packages -by making them behave in a runtime-pure manner. To make this happen, we -recommend that you set up a project-specific `.Rprofile` using -`rix::rix_init()`. This way, only packages declaratively defined in your -`default.nix` and built to be part of the Nix store (one R package is one -separate derivation listed in a unique Nix path) appear on the R library path. - -As an example, call `rix::rix()` like this. - -``` r - -# see ?rix_init for more details - -rix_init( - project_path = "./rix_darwin", - rprofile_action = "create_missing" -) -``` - +libraries from the system would also appear on the search path in R from +`nixpkgs` for Linux, running `rix()` also runs `rix_init()` which creates a +custom `.Rprofile` in your project's path. This custom `.Rprofile` ensure that +only packages declaratively defined in your `default.nix` and built to be part +of the Nix store (one R package is one separate derivation listed in a unique +Nix path) appear on the R library path. ### RStudio and other development interfaces on macOS @@ -201,4 +186,3 @@ Nix store to the `PATH` variable in an active session automatically (via `Sys.setenv()`, when you use RStudio on macOS. You don't have to do anything. We have you covered, and you get a friendly message that informs you. special side effect. - diff --git a/vignettes/c-using-rix-to-build-project-specific-environments.Rmd b/vignettes/c-using-rix-to-build-project-specific-environments.Rmd index 5b3e8ad9..3f8324d2 100644 --- a/vignettes/c-using-rix-to-build-project-specific-environments.Rmd +++ b/vignettes/c-using-rix-to-build-project-specific-environments.Rmd @@ -163,7 +163,6 @@ version 4.0.0 for example in a subshell (or execute a function that requires an old version of a package in that subshell), and get the result of the computation back into the main R session. - ## Nix environments are not completely isolated from your system It is important to know that an environment built by Nix is not totally isolated @@ -172,8 +171,20 @@ your system, and suppose you build a Nix environment that also comes with `sl`. If you activate that environment, the version of `sl` that will run when called is the one included in the Nix environment. If, however, you start `sl` in a Nix environment that does not come with it, then your system's `sl` will get used -instead. It is also possible to completely isolate an environment built with Nix -using the provided `rix_init()` function and activate your environment using -`nix-shell --pure` instead of only `nix-shell`. This is especially useful for -subshells. +instead. + +In the context of the R programming language, this means that if you have a user +or system library of packages (meaning, a library of packages generated by a +regular installation of R), these packages may be loaded by an R version running +from a Nix shell. To avoid issues with this, calling `rix()` automatically runs +`rix_init()` as well, which generates a custom `.Rprofile` file in the project's +directory. This way, your regular user library of packages will not interfere +with R environments managed by Nix. Moreover, this custom `.Rprofile` also +redefines `install.packages()` and makes it throw an error: indeed, if you wish +to add packages to your an R environment managed by Nix, you should add these +packages to the `default.nix` file instead, and rebuild the environment. + +If you want to even make other programs inaccessible to a running Nix +environment, you can drop into it using `nix-shell --pure` instead of only +`nix-shell`. diff --git a/vignettes/e-interactive-use.Rmd b/vignettes/e-interactive-use.Rmd index 315aade3..6fa6541b 100644 --- a/vignettes/e-interactive-use.Rmd +++ b/vignettes/e-interactive-use.Rmd @@ -31,7 +31,6 @@ It is also possible to evaluate single functions inside a dedicated, separate, environment from another, main, interactive R session. For more details regarding this, refer to the vignette `vignette("z-advanced-topic-running-r-or-shell-code-in-nix-from-r")`. - ## Scenario 1: you installed R and RStudio using the usual installers Let's suppose that you are already running R and RStudio and that you wish to @@ -89,30 +88,30 @@ rix(r_ver = "latest", ``` Because you also have R installed through the usual method for your operating -system, you also have a system or user library of packages. This library of +system, you also have a system or user library of packages. This library of packages will interfere with the library of packages of your R environments -managed by Nix. We thus highly recommend to also run `rix::rix_init()` in your -project’s path (in the example above, in `path_to_project` to generate a .Rprofile -that will prevent clashes between your user library of packages ar the Nix -environments’ library of packages. +managed by Nix. To avoid this, running `rix()` not only writes a `default.nix` +file in your project's path, but also a custom `.Rprofile` file as well by +calling `rix_init()`. This `.Rprofile` will prevent clashes between your user +library of packages and the Nix environments’ library of packages. Navigate to that folder using your terminal, and then run `nix-build` to build -the environment, and then `nix-shell`. You will -then be *dropped into* a Nix shell. You can also use `nix-shell --pure` instead, -if you want to increase the isolation of your Nix-R environments. -The difference is that in an environment started with `nix-shell`, you will still -be able to access programs from your system, while with `nix-shell --pure`, only -programs installed for that Nix-R environment will be available. Try something like -`which wget` from a shell started with `nix-shell` and then from a shell started -with `nix-shell --pure` as an example (replace `wget` by any other tool you have -installed on your computer). - -Once in the shell, you can type `rstudio` to run -this project specific version of R and RStudio with all the required packages -for this project, in this case `{dplyr}` and `{ggplot2}`. If you get an error +the environment, and then `nix-shell`. You will then be *dropped into* a Nix +shell. You can also use `nix-shell --pure` instead, if you want to increase the +isolation of your Nix-R environments. The difference is that in an environment +started with `nix-shell`, you will still be able to access programs from your +system, while with `nix-shell --pure`, only programs installed for that Nix-R +environment will be available. Try something like `which wget` from a shell +started with `nix-shell` and then from a shell started with `nix-shell --pure` +as an example (replace `wget` by any other tool you have installed on your +computer). + +Once in the shell, you can type `rstudio` to run this project specific version +of R and RStudio with all the required packages for this project, in this case +`{dplyr}` and `{ggplot2}`. If you get an error ``` -qt.glx: qglx_findConfig: Failed to finding... +qt.glx: qglx_findConfig: Failed to finding... qt.glx: qglx_findConfig: Failed to finding... Could not initialize GLX Aborted (core dumped) @@ -125,7 +124,7 @@ export QT_XCB_GL_INTEGRATION=none ``` This should solve the issue. In any case, we would be thankful if you opened -an issue if you encountered this bug and if the fix worked for you. +an issue if you encountered this bug and if the fix worked for you. You can then work on it as usual. @@ -173,12 +172,12 @@ session inside your terminal. You can now run something like this: to generate a `default.nix`, and then use that file to generate an environment with R, Rstudio, `{dplyr}` and `{ggplot2}`. If you need to add packages for your -project, rerun the command above, but add the needed packages to `r_pkgs`. If you -need to create a new environment, you could rerun the command above, or you +project, rerun the command above, but add the needed packages to `r_pkgs`. If +you need to create a new environment, you could rerun the command above, or you could install `{rix}` in that environment to generate new `default.nix` files. Here, there is no need to use `rix_init()` as there won’t be any clash between -your user library of R packages (since you don’t have any), and the R environments -managed by Nix. +your user library of R packages (since you don’t have any), and the R +environments managed by Nix. ## Scenario 3: you use some IDE other than RStudio @@ -209,14 +208,8 @@ Codium over VS Code. For any other editor such as Emacs or Vim, set `ide = "other"`. Also use `ide = "other"` if you want to run scripts non-interactively, for example on a CI/CD service. -Just as in scenario 1, if you already have R installed through the usual means -for your operating system, we highly recommend using `rix::rix_init()` to avoid -your system or user library of R packages to clash with the library of environments -managed by Nix. - ## Conclusion You now know the basics of Nix and `{rix}` and can start using it for your projects! There are still some more vignettes that we recommend you read which cover advanced topics. - diff --git a/vignettes/z-advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd b/vignettes/z-advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd index 07e75421..d6a43d0e 100644 --- a/vignettes/z-advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd +++ b/vignettes/z-advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd @@ -78,49 +78,16 @@ from the R changelog, the following [literal entry in R The goal is to illustrate this change in behavior from R versions 4.1.3 and before to R versions 4.2.0 and later. - ### Setting up the (R) software environment with Nix -We first create a isolated directory to prepare for a Nix environment, and write -a custom `.Rprofile` file as well. By default, the R derivation in Nixpkgs -includes the user library at first position (returned by `.libPaths()`). Startup -code written to this local `.Rprofile` will make sure that the system's user -library (`R_LIBS_USER`) is excluded from library paths to load packages from. -This is nice to install packages from a Nix-R session environment in ad-hoc and -interactive manner. However, this comes at the cost that one needs be aware of -potential run-time pollution of packages outside the pool of paths per package -from the nix store. On macOS, we experienced a high-chance of segmentation -faults when accidentally loading packages and linked system libraries from the -system's user library, to give an example. `rix::rix_init()` writes a configuration -that takes care of runtime-pure R package libraries from declaratively defined -Nix builds. Additionally, it modifies `.libPaths()` in the running R session. - - -```{r parsermd-chunk-1} +First, we write a `default.nix` file containing Nix expressions that pin R +version 4.1.3 from Nixpkgs. + +```{r parsermd-chunk-3} library("rix") path_env_1 <- file.path(".", "_env_1_R-4-1-3") -rix_init( - project_path = path_env_1, - rprofile_action = "overwrite", - message_type = "simple" -) -list.files(path = path_env_1, all.files = TRUE) -``` - -This will generate the following `.Rprofile` file. - - -```{r parsermd-chunk-2, echo = FALSE} -cat(readLines(file.path(path_env_1, ".Rprofile")), sep = "\n") -``` - -Next, we write a `default.nix` file containing Nix expressions that pin R -version 4.2.0 from Nixpkgs. - - -```{r parsermd-chunk-3} rix( r_ver = "4.1.3", overwrite = TRUE, @@ -131,14 +98,16 @@ rix( The following expression is written to default.nix in the subfolder `./_env_1_R-4-1-3/`. - ```{r parsermd-chunk-4, echo = FALSE} cat(readLines(file.path(path_env_1, "default.nix")), sep = "\n") ``` +This also includes a custom `.Rprofile` file that ensure that this subshell +will not load any packages installed to the user's library of packages. + ### Defining and interactively testing custom R code with function(s) -We know have set up the configuration for R 4.1.3 set up in a `default.nix` file +We now have set up the configuration for R 4.1.3 set up in a `default.nix` file in the folder `./_env_1_R-4-1-3`. Since you are sure you are using an R version higher 4.2.0 available on your system, you can check what that `as.vector.data.frame()` S3 method returns a list. @@ -149,10 +118,9 @@ df <- data.frame(a = 1:3, b = 4:6) as.vector(x = df, mode ="list") ``` -This is is different for R versions 4.1.3 and below, where you should get an +This is different for R versions 4.1.3 and below, where you should get an identical data frame back. - ### Run functioned up code and investigate results produced in pure Nix Rsoftware environments To formally validate in a 'System-to-Nix' approach that the object returned from @@ -196,7 +164,6 @@ store. This will take a bit of time to get the cache. You will see in your current R console the specific Nix paths that will be downloaded and copied into your Nix store automatically. - ```{r parsermd-chunk-7, eval = FALSE} # now run it in `nix-shell`; `with_nix()` takes care # of exporting global objects of `df_as_vector` recursively @@ -298,7 +265,6 @@ session with R 4.1.3. You did not need to type in R first, because we set up a R shell hook via `rix::rix()`. Next, we define again the target function to test in R 4.2.0, too. - ```{r parsermd-chunk-13, eval = FALSE} # current Nix-R session with R 4.1.3 df_as_vector <- function(x) { @@ -320,7 +286,6 @@ out_nix_1_2 <- with_nix( You can now formally compare the outputs of the computation of the same code in R 4.1.3 vs. R 4.2.0 environments controlled by Nix. - ```{r parsermd-chunk-15, eval = FALSE} identical(out_nix_1, out_nix_1_2) # yields FALSE @@ -344,7 +309,6 @@ would return the character `"a"`. However, this behaviour is unexpected: it really should return an error. This was addressed in versions after 1.5.0: - ```{r parsermd-chunk-17, eval = FALSE} out_system_stringr <- tryCatch( expr = {stringr::str_subset(c("", "a"), "")}, @@ -359,36 +323,23 @@ Let's build a subshell with the latest version of R, but an older version of `{stringr}`: - ```{r parsermd-chunk-18} library("rix") path_env_stringr <- file.path(".", "_env_stringr_1.4.1") -rix_init( - project_path = path_env_stringr, - rprofile_action = "overwrite", - message_type = "simple" -) - -list.files(path = path_env_stringr, all.files = TRUE) -``` - -The call below generates a `default.nix` file for the subshell with the -old version of `{stringr}`: - - -```{r parsermd-chunk-19, eval = FALSE} rix( r_ver = "latest", r_pkgs = "stringr@1.4.1", overwrite = TRUE, project_path = path_env_stringr ) + +list.files(path = path_env_stringr, all.files = TRUE) ``` -We can now run the code in the subshell +We can now run the code in the subshell ```{r parsermd-chunk-20, eval = FALSE} out_nix_stringr <- with_nix( @@ -424,7 +375,6 @@ identical(out_system_stringr, out_nix_stringr) As expected, the result is `FALSE`. - ## **Case study 3: Using a subshell to get hard to install dependencies** Nix subshells are quite useful in cases where you need to use a package that @@ -435,33 +385,26 @@ load data and bring it down to a manageable size (using `select()` and `filter()` for instance). This use cases illustrates how to achieve this. Let's start by building a subshell that is based on a distinct revision of -nixpkgs, for which we know that arrow compiles on both linux and macOS (darwin). - +`nixpkgs`, for which we know that arrow compiles on both linux and macOS +(darwin). ```{r parsermd-chunk-22, eval = FALSE} library("rix") path_env_arrow <- file.path("env_arrow") -rix_init( - project_path = path_env_arrow, - rprofile_action = "overwrite", - message_type = "simple" -) - rix( r_ver = "4.1.1", r_pkgs = c("dplyr", "arrow"), overwrite = TRUE, project_path = path_env_arrow ) -``` -This specific revision of R contains `{arrow}` 13. Let's now -suppose that you already have a script with some code to -load and transform some data using `{arrow}`. It may look -something like this: +``` +This specific revision of R contains `{arrow}` 13. Let's now suppose that you +already have a script with some code to load and transform some data using +`{arrow}`. It may look something like this: ```{r parsermd-chunk-23, eval = FALSE} library(arrow) @@ -476,7 +419,6 @@ arrow_cars %>% To run this code in a subshell, we recommend wrapping it inside a function: - ```{r parsermd-chunk-24, eval = FALSE} arrow_script <- function() { library(arrow) @@ -493,7 +435,6 @@ arrow_script <- function() { Which we can then run in the subshell: - ```{r parsermd-chunk-25, eval = FALSE} out_nix_arrow <- with_nix( expr = function() arrow_script(), @@ -506,4 +447,3 @@ out_nix_arrow <- with_nix( This will run the function in the subshell, and its output will be saved in the `out_nix_arrow` variable, for further manipulation in your main shell/session. - From 3caf8adccc325dfe0f60764f9a949cca36929c60 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 10:36:33 +0200 Subject: [PATCH 05/21] documentation --- R/rix.R | 65 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/R/rix.R b/R/rix.R index 4a1acf86..8255f3c7 100644 --- a/R/rix.R +++ b/R/rix.R @@ -1,18 +1,19 @@ -#' Generate a Nix expression that builds a reproducible development -#' environment -#' @return Nothing, this function only has the side-effect of writing a file -#' called "default.nix" in the working directory. This file contains the -#' expression to build a reproducible environment using the Nix package -#' manager. +#' Generate a Nix expression that builds a reproducible development environment +#' @return Nothing, this function only has the side-effect of writing two files: +#' `default.nix` and `.Rprofile` in the working directory. `default.nix` +#' contains a Nix expression to build a reproducible environment using the Nix +#' package manager, and `.Rprofile` ensures that a running R session from a +#' Nix environment cannot access local libraries, nor install packages using +#' `install.packages()`. #' @param r_ver Character, defaults to "latest". The required R version, for #' example "4.0.0". You can check which R versions are available using -#' `available_r`. For reproducibility purposes, you can also provide a nixpkgs -#' revision directly. For older versions of R, `nix-build` might fail with an -#' error stating 'this derivation is not meant to be built'. In this case, -#' simply drop into the shell with `nix-shell` instead of building it first. -#' It is also possible to provide either "bleeding_edge" or +#' `available_r()`. For reproducibility purposes, you can also provide a +#' `nixpkgs` revision directly. For older versions of R, `nix-build` might +#' fail with an error stating 'this derivation is not meant to be built'. In +#' this case, simply drop into the shell with `nix-shell` instead of building +#' it first. It is also possible to provide either "bleeding_edge" or #' "frozen_edge" if you need an environment with bleeding edge packages. Read -#' more in the "Details" below. +#' more in the "Details" section below. #' @param r_pkgs Vector of characters. List the required R packages for your #' analysis here. #' @param system_pkgs Vector of characters. List further software you wish to @@ -20,10 +21,11 @@ #' example. You can look for available software on the NixOS website #' \url{https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=} #' @param git_pkgs List. A list of packages to install from Git. See details for -#' more information. -#' @param local_pkgs List. A list of paths to local packages to install. These -#' packages need to be in the `.tar.gz` or `.zip` formats. -#' @param tex_pkgs Vector of characters. A set of tex packages to install. Use +#' more information. +#' @param local_pkgs List. A list of local packages to install. These packages +#' need to be in the `.tar.gz` or `.zip` formats and must be in the same +#' folder as the generated "default.nix" file. +#' @param tex_pkgs Vector of characters. A set of TeX packages to install. Use #' this if you need to compile `.tex` documents, or build PDF documents using #' Quarto. If you don't know which package to add, start by adding "amsmath". #' See the Vignette "Authoring LaTeX documents" for more details. @@ -33,26 +35,25 @@ #' other editors, use "other". This has been tested with RStudio, VS Code and #' Emacs. If other editors don't work, please open an issue. #' @param project_path Character, defaults to the current working directory. -#' Where to write `default.nix`, for example "/home/path/to/project". -#' The file will thus be written to the file -#' "/home/path/to/project/default.nix". +#' Where to write `default.nix`, for example "/home/path/to/project". The file +#' will thus be written to the file "/home/path/to/project/default.nix". #' @param overwrite Logical, defaults to FALSE. If TRUE, overwrite the #' `default.nix` file in the specified path. #' @param print Logical, defaults to FALSE. If TRUE, print `default.nix` to -#' console. +#' console. #' @param shell_hook Character of length 1, defaults to `NULL`. Commands added -#' to the `shellHook` variable executed when the Nix shell starts. So -#' by default, using `nix-shell default.nix` (or path with `shell.nix`) will -#' start a specific program, possibly with flags (separated by space), and/or -#' do shell actions. You can for example use `shell_hook = R`, if you want to -#' directly enter the declared Nix R session. -#' @details This function will write a `default.nix` in the chosen path. Using -#' the Nix package manager, it is then possible to build a reproducible -#' development environment using the `nix-build` command in the path. This -#' environment will contain the chosen version of R and packages, and will not -#' interfere with any other installed version (via Nix or not) on your -#' machine. Every dependency, including both R package dependencies but also -#' system dependencies like compilers will get installed as well in that +#' to the `shellHook` variable are executed when the Nix shell starts. So by +#' default, using `nix-shell default.nix` will start a specific program, +#' possibly with flags (separated by space), and/or do shell actions. You can +#' for example use `shell_hook = R`, if you want to directly enter the +#' declared Nix R session when dropping into the Nix shell. +#' @details This function will write a `default.nix` and an `.Rprofile` in the +#' chosen path. Using the Nix package manager, it is then possible to build a +#' reproducible development environment using the `nix-build` command in the +#' path. This environment will contain the chosen version of R and packages, +#' and will not interfere with any other installed version (via Nix or not) on +#' your machine. Every dependency, including both R package dependencies but +#' also system dependencies like compilers will get installed as well in that #' environment. #' #' It is possible to use environments built with Nix interactively, either From 23be343592d40e93b307e90ea4ee75e9f55d7e3e Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 11:41:21 +0200 Subject: [PATCH 06/21] handle situations where two description files are present in the package (one for testing) --- R/fetchers.R | 4 + R/rix.R | 58 +++++---- R/rix_init.R | 60 ++++----- inst/extdata/default.nix | 12 +- man/rix.Rd | 116 ++++++++++-------- man/rix_init.Rd | 56 +++++---- man/with_nix.Rd | 2 +- tests/testthat/test-rix.R | 38 ++++++ ...alling-r-packages-in-a-nix-environment.Rmd | 39 +++--- 9 files changed, 227 insertions(+), 158 deletions(-) diff --git a/R/fetchers.R b/R/fetchers.R index 6a964e1c..acb91a4f 100644 --- a/R/fetchers.R +++ b/R/fetchers.R @@ -118,6 +118,10 @@ remove_base <- function(list_imports) { get_imports <- function(path) { tmp_dir <- tempdir() + # Some packages have a Description file in the testthat folder + # (see jimhester/lookup) so we need to get rid of that + path <- Filter(function(x)!grepl("testthat", x), path) + # Is the path pointing to a tar.gz archive # or directly to a DESCRIPTION file? if (grepl("\\.tar\\.gz", path)) { diff --git a/R/rix.R b/R/rix.R index 8255f3c7..5c741e9b 100644 --- a/R/rix.R +++ b/R/rix.R @@ -36,7 +36,8 @@ #' Emacs. If other editors don't work, please open an issue. #' @param project_path Character, defaults to the current working directory. #' Where to write `default.nix`, for example "/home/path/to/project". The file -#' will thus be written to the file "/home/path/to/project/default.nix". +#' will thus be written to the file "/home/path/to/project/default.nix". If +#' the folder does not exist, it will be created. #' @param overwrite Logical, defaults to FALSE. If TRUE, overwrite the #' `default.nix` file in the specified path. #' @param print Logical, defaults to FALSE. If TRUE, print `default.nix` to @@ -57,17 +58,18 @@ #' environment. #' #' It is possible to use environments built with Nix interactively, either -#' from the terminal, or using an interface such as RStudio. If you -#' want to use RStudio, set it to `"rstudio"`. Please be aware that RStudio -#' is not available for macOS through Nix. As such, you may want to use another -#' editor on macOS. To use Visual Studio Code (or Codium), set the `ide` -#' argument to `"code"`, which will add the `{languageserver}` R package -#' to the list of R packages to be installed by Nix in that environment. You can -#' use the version of Visual Studio Code or Codium you already use, or also install -#' it using Nix (by adding "vscode" or "vscodium" to the list of `system_pkgs`). -#' For non-interactive use, or to use the environment from the command line, or from another -#' editor (such as Emacs or Vim), set the `ide` argument to `"other"`. -#' We recommend reading the `vignette("e-interactive-use")` for more details. +#' from the terminal, or using an interface such as RStudio. If you want to +#' use RStudio, set the `ide` argument to `"rstudio"`. Please be aware that +#' RStudio is not available for macOS through Nix. As such, you may want to +#' use another editor on macOS. To use Visual Studio Code (or Codium), set the +#' `ide` argument to `"code"`, which will add the `{languageserver}` R package +#' to the list of R packages to be installed by Nix in that environment. You +#' can use the version of Visual Studio Code or Codium you already use, or +#' also install it using Nix (by adding "vscode" or "vscodium" to the list of +#' `system_pkgs`). For non-interactive use, or to use the environment from the +#' command line, or from another editor (such as Emacs or Vim), set the `ide` +#' argument to `"other"`. We recommend reading the +#' `vignette("e-interactive-use")` for more details. #' #' Packages to install from Github must be provided in a list of 4 elements: #' "package_name", "repo_url", "branch_name" and "commit". This argument can @@ -83,7 +85,13 @@ #' setting `r_ver = "3.1.0"`, which was the version of R current at the time. #' This ensures that Nix builds a completely coherent environment. #' -#' By default, the nix shell will be configured with `"en_US.UTF-8"` for the +#' Note that installing packages from Git or old versions using the `"@"` +#' notation or local packages, does not leverage Nix's capabilities for +#' dependency solving. As such, you might have trouble installing these +#' packages. If that is the case, open an issue on `{rix}`'s Github +#' repository. +#' +#' By default, the Nix shell will be configured with `"en_US.UTF-8"` for the #' relevant locale variables (`LANG`, `LC_ALL`, `LC_TIME`, `LC_MONETARY`, #' `LC_PAPER`, `LC_MEASUREMENT`). This is done to ensure locale #' reproducibility by default in Nix environments created with `rix()`. If @@ -92,18 +100,18 @@ #' list(LANG = "de_CH.UTF-8", <...>)` and the aforementioned locale variable #' names. #' -#' It is possible to use "bleeding_edge" or "frozen_edge" as the value for the -#' `r_ver` argument. This will create an environment with the very latest R -#' packages. "bleeding_edge" means that every time you will build the +#' It is possible to use `"bleeding_edge`" or `"frozen_edge`" as the value for +#' the `r_ver` argument. This will create an environment with the very latest +#' R packages. `"bleeding_edge`" means that every time you will build the #' environment, the packages will get updated. This is especially useful for #' environments that need to be constantly updated, for example when -#' developing a package. In contrast, "frozen_edge" will create an environment -#' that will remain stable at build time. So if you create a `default.nix` -#' file using "bleeding_edge", each time you build it using `nix-build` that -#' environment will be up-to-date. With "frozen_edge" that environment will be -#' up-to-date on the date that the `default.nix` will be generated, and then -#' each subsequent call to `nix-build` will result in the same environment. We -#' highly recommend you read the vignette titled +#' developing a package. In contrast, `"frozen_edge`" will create an +#' environment that will remain stable at build time. So if you create a +#' `default.nix` file using `"bleeding_edge`", each time you build it using +#' `nix-build` that environment will be up-to-date. With `"frozen_edge`" that +#' environment will be up-to-date on the date that the `default.nix` will be +#' generated, and then each subsequent call to `nix-build` will result in the +#' same environment. We highly recommend you read the vignette titled #' "z - Advanced topic: Understanding the rPackages set release cycle and using bleeding edge packages". #' @export #' @examples @@ -134,6 +142,7 @@ rix <- function(r_ver = "latest", overwrite = FALSE, print = FALSE, shell_hook = NULL) { + if (r_ver %in% c("bleeding_edge", "frozen_edge")) { warning( "You chose 'bleeding_edge' or 'frozen_edge' as the value for @@ -180,7 +189,7 @@ for more details." if (isFALSE(dir.exists(project_path))) { dir.create(path = project_path, recursive = TRUE) project_path <- normalizePath(path = project_path) - } + } default.nix_path <- if (project_path == ".") { "default.nix" @@ -271,6 +280,7 @@ for more details." rix_init(project_path = project_path, rprofile_action = "create_missing", message_type = "quiet") + cat("\nSuccessfully generated `default.nix` and `.Rprofile`\n") } else { project_path <- if(project_path == ".") { "current folder" diff --git a/R/rix_init.R b/R/rix_init.R index 9fbd057a..8d10b3f2 100644 --- a/R/rix_init.R +++ b/R/rix_init.R @@ -15,13 +15,13 @@ #' reproducibility of Nix-R environments during runtime. Concretely, if you #' already have a system or user library of R packages (if you have R installed #' through the usual means for your operating system), using `rix::rix_init()` -#' will prevent Nix-R environments to load packages from the user library -#' which would cause issues. -#' Notably, no restart is required as environmental variables are set in the current session, in -#' addition to writing an `.Rprofile` file. This is particularly useful to make -#' [rix::with_nix()] evaluate custom R functions from any "Nix-to-Nix" or -#' "System-to-Nix" R setups. It introduces two side-effects that -#' take effect both in a current or later R session setup: +#' will prevent Nix-R environments to load packages from the user library which +#' would cause issues. Notably, no restart is required as environmental +#' variables are set in the current session, in addition to writing an +#' `.Rprofile` file. This is particularly useful to make [rix::with_nix()] +#' evaluate custom R functions from any "Nix-to-Nix" or "System-to-Nix" R +#' setups. It introduces two side-effects that take effect both in a current or +#' later R session setup: #' #' 1. **Adjusting `R_LIBS_USER` path:** #' By default, the first path of `R_LIBS_USER` points to the user library @@ -41,9 +41,9 @@ #' In a host RStudio session not launched via Nix (`nix-shell`), the #' environmental variables from `~/.zshrc` or `~/.bashrc` may not be #' inherited. Consequently, Nix command line interfaces like `nix-shell` -#' might not be found. The `.Rprofile` code written by `rix::rix_init()` ensures -#' that Nix command line programs are accessible by adding the path of the -#' "bin" directory of the default Nix profile, +#' might not be found. The `.Rprofile` code written by `rix::rix_init()` +#' ensures that Nix command line programs are accessible by adding the path +#' of the "bin" directory of the default Nix profile, #' `"/nix/var/nix/profiles/default/bin"`, to the `PATH` variable in an #' RStudio R session. #' @@ -55,28 +55,32 @@ #' packaged for macOS. We recommend calling `rix::rix_init()` prior to comparing R #' code ran between two software environments with `rix::with_nix()`. #' -#' @param project_path Character with the folder path to the isolated nix-R project. -#' Defaults to `"."`, which is the current working directory path. If the folder -#' does not exist yet, it will be created. +#' `rix::rix_init()` is called automatically by `rix::rix()` when generating a +#' `default.nix` file, and when called by `rix::rix()` will only add the `.Rprofile` +#' if none exists. In case you have a custom `.Rprofile` that you wish to keep +#' using, but also want to benefit from what `rix_init()` offers, manually call +#' it and set the `rprofile_action` to `"append"`. +#' +#' @param project_path Character with the folder path to the isolated nix-R +#' project. Defaults to `"."`, which is the current working directory path. If +#' the folder does not exist yet, it will be created. #' @param rprofile_action Character. Action to take with `.Rprofile` file -#' destined for `project_path` folder. Possible values include -#' `"create_missing"`, which only writes `.Rprofile` if it -#' does not yet exist (otherwise does nothing); `"create_backup"`, which copies -#' the existing `.Rprofile` to a new backup file, generating names with -#' POSIXct-derived strings that include the time zone information. A new -#' `.Rprofile` file will be written with default code from `rix::rix_init()`; -#' `"overwrite"` overwrites the `.Rprofile` file if it does exist; `"append"` -#' appends the existing file with code that is tailored to an isolated Nix-R -#' project setup. +#' destined for `project_path` folder. Possible values include +#' `"create_missing"`, which only writes `.Rprofile` if it does not yet exist +#' (otherwise does nothing) - this is the action set when using `rix()` - ; +#' `"create_backup"`, which copies the existing `.Rprofile` to a new backup +#' file, generating names with POSIXct-derived strings that include the time +#' zone information. A new `.Rprofile` file will be written with default code +#' from `rix::rix_init()`; `"overwrite"` overwrites the `.Rprofile` file if it +#' does exist; `"append"` appends the existing file with code that is tailored +#' to an isolated Nix-R project setup. #' @param message_type Character. Message type, defaults to `"simple"`, which -#' gives minimal but sufficient feedback. Other values are currently -#' `"quiet`, which writes `.Rprofile` without message, and -#' `"verbose"`, which displays the mechanisms implemented to achieve fully -#' controlled R project environments in Nix. +#' gives minimal but sufficient feedback. Other values are currently +#' `"quiet`, which writes `.Rprofile` without message, and `"verbose"`, +#' which displays the mechanisms implemented to achieve fully controlled R project environments in Nix. #' @export #' @seealso [with_nix()] -#' @return Nothing, this function only has the side-effect of writing a file -#' called ".Rprofile" to the specified path. +#' @return Nothing, this function only has the side-effect of writing a file called ".Rprofile" to the specified path. #' @examples #' \dontrun{ #' # create an isolated, runtime-pure R setup via Nix diff --git a/inst/extdata/default.nix b/inst/extdata/default.nix index 76b70e90..629c9760 100644 --- a/inst/extdata/default.nix +++ b/inst/extdata/default.nix @@ -1,6 +1,6 @@ -# This file was generated by the {rix} R package v0.7.1 on 2024-06-28 +# This file was generated by the {rix} R package v0.7.1 on 2024-07-01 # with following call: -# >rix(r_ver = "1e3deb3d8a86a870d925760db1a5adecc64d329d", +# >rix(r_ver = "12a9c0004bc987afb1ff511ebb97b67497a68e22", # > r_pkgs = NULL, # > system_pkgs = NULL, # > git_pkgs = list(package_name = "rix", @@ -11,11 +11,11 @@ # > project_path = "../inst/extdata", # > overwrite = TRUE, # > shell_hook = NULL) -# It uses nixpkgs' revision 1e3deb3d8a86a870d925760db1a5adecc64d329d for reproducibility purposes +# It uses nixpkgs' revision 12a9c0004bc987afb1ff511ebb97b67497a68e22 for reproducibility purposes # which will install R version latest. # Report any issues to https://github.com/b-rodrigues/rix let - pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/1e3deb3d8a86a870d925760db1a5adecc64d329d.tar.gz") {}; + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; git_archive_pkgs = [ (pkgs.rPackages.buildRPackage { @@ -23,8 +23,8 @@ let src = pkgs.fetchgit { url = "https://github.com/b-rodrigues/rix/"; branchName = "master"; - rev = "9e3bdfa6c508a2a549aae9e41c14d2ead0a9191d"; - sha256 = "sha256-uYjCuH7z7enk6i0Kb2inErXdfDA2OkKei8jr3HvKNh0="; + rev = "ad53dccd9f87e56a5c9e486b11e5c8f659fcb162"; + sha256 = "sha256-spwHEm6ohT5p2Ef8GNbsMjyL3FgMoAvCn7mQjZ2ruQs="; }; propagatedBuildInputs = builtins.attrValues { inherit (pkgs.rPackages) diff --git a/man/rix.Rd b/man/rix.Rd index 7f898651..1812c539 100644 --- a/man/rix.Rd +++ b/man/rix.Rd @@ -2,8 +2,7 @@ % Please edit documentation in R/rix.R \name{rix} \alias{rix} -\title{Generate a Nix expression that builds a reproducible development -environment} +\title{Generate a Nix expression that builds a reproducible development environment} \usage{ rix( r_ver = "latest", @@ -22,13 +21,13 @@ rix( \arguments{ \item{r_ver}{Character, defaults to "latest". The required R version, for example "4.0.0". You can check which R versions are available using -\code{available_r}. For reproducibility purposes, you can also provide a nixpkgs -revision directly. For older versions of R, \code{nix-build} might fail with an -error stating 'this derivation is not meant to be built'. In this case, -simply drop into the shell with \code{nix-shell} instead of building it first. -It is also possible to provide either "bleeding_edge" or +\code{available_r()}. For reproducibility purposes, you can also provide a +\code{nixpkgs} revision directly. For older versions of R, \code{nix-build} might +fail with an error stating 'this derivation is not meant to be built'. In +this case, simply drop into the shell with \code{nix-shell} instead of building +it first. It is also possible to provide either "bleeding_edge" or "frozen_edge" if you need an environment with bleeding edge packages. Read -more in the "Details" below.} +more in the "Details" section below.} \item{r_pkgs}{Vector of characters. List the required R packages for your analysis here.} @@ -41,10 +40,11 @@ example. You can look for available software on the NixOS website \item{git_pkgs}{List. A list of packages to install from Git. See details for more information.} -\item{local_pkgs}{List. A list of paths to local packages to install. These -packages need to be in the \code{.tar.gz} or \code{.zip} formats.} +\item{local_pkgs}{List. A list of local packages to install. These packages +need to be in the \code{.tar.gz} or \code{.zip} formats and must be in the same +folder as the generated "default.nix" file.} -\item{tex_pkgs}{Vector of characters. A set of tex packages to install. Use +\item{tex_pkgs}{Vector of characters. A set of TeX packages to install. Use this if you need to compile \code{.tex} documents, or build PDF documents using Quarto. If you don't know which package to add, start by adding "amsmath". See the Vignette "Authoring LaTeX documents" for more details.} @@ -56,9 +56,9 @@ other editors, use "other". This has been tested with RStudio, VS Code and Emacs. If other editors don't work, please open an issue.} \item{project_path}{Character, defaults to the current working directory. -Where to write \code{default.nix}, for example "/home/path/to/project". -The file will thus be written to the file -"/home/path/to/project/default.nix".} +Where to write \code{default.nix}, for example "/home/path/to/project". The file +will thus be written to the file "/home/path/to/project/default.nix". If +the folder does not exist, it will be created.} \item{overwrite}{Logical, defaults to FALSE. If TRUE, overwrite the \code{default.nix} file in the specified path.} @@ -67,44 +67,46 @@ The file will thus be written to the file console.} \item{shell_hook}{Character of length 1, defaults to \code{NULL}. Commands added -to the \code{shellHook} variable executed when the Nix shell starts. So -by default, using \verb{nix-shell default.nix} (or path with \code{shell.nix}) will -start a specific program, possibly with flags (separated by space), and/or -do shell actions. You can for example use \code{shell_hook = R}, if you want to -directly enter the declared Nix R session.} +to the \code{shellHook} variable are executed when the Nix shell starts. So by +default, using \verb{nix-shell default.nix} will start a specific program, +possibly with flags (separated by space), and/or do shell actions. You can +for example use \code{shell_hook = R}, if you want to directly enter the +declared Nix R session when dropping into the Nix shell.} } \value{ -Nothing, this function only has the side-effect of writing a file -called "default.nix" in the working directory. This file contains the -expression to build a reproducible environment using the Nix package -manager. +Nothing, this function only has the side-effect of writing two files: +\code{default.nix} and \code{.Rprofile} in the working directory. \code{default.nix} +contains a Nix expression to build a reproducible environment using the Nix +package manager, and \code{.Rprofile} ensures that a running R session from a +Nix environment cannot access local libraries, nor install packages using +\code{install.packages()}. } \description{ -Generate a Nix expression that builds a reproducible development -environment +Generate a Nix expression that builds a reproducible development environment } \details{ -This function will write a \code{default.nix} in the chosen path. Using -the Nix package manager, it is then possible to build a reproducible -development environment using the \code{nix-build} command in the path. This -environment will contain the chosen version of R and packages, and will not -interfere with any other installed version (via Nix or not) on your -machine. Every dependency, including both R package dependencies but also -system dependencies like compilers will get installed as well in that +This function will write a \code{default.nix} and an \code{.Rprofile} in the +chosen path. Using the Nix package manager, it is then possible to build a +reproducible development environment using the \code{nix-build} command in the +path. This environment will contain the chosen version of R and packages, +and will not interfere with any other installed version (via Nix or not) on +your machine. Every dependency, including both R package dependencies but +also system dependencies like compilers will get installed as well in that environment. It is possible to use environments built with Nix interactively, either -from the terminal, or using an interface such as RStudio. If you -want to use RStudio, set it to \code{"rstudio"}. Please be aware that RStudio -is not available for macOS through Nix. As such, you may want to use another -editor on macOS. To use Visual Studio Code (or Codium), set the \code{ide} -argument to \code{"code"}, which will add the \code{{languageserver}} R package -to the list of R packages to be installed by Nix in that environment. You can -use the version of Visual Studio Code or Codium you already use, or also install -it using Nix (by adding "vscode" or "vscodium" to the list of \code{system_pkgs}). -For non-interactive use, or to use the environment from the command line, or from another -editor (such as Emacs or Vim), set the \code{ide} argument to \code{"other"}. -We recommend reading the \code{vignette("e-interactive-use")} for more details. +from the terminal, or using an interface such as RStudio. If you want to +use RStudio, set the \code{ide} argument to \code{"rstudio"}. Please be aware that +RStudio is not available for macOS through Nix. As such, you may want to +use another editor on macOS. To use Visual Studio Code (or Codium), set the +\code{ide} argument to \code{"code"}, which will add the \code{{languageserver}} R package +to the list of R packages to be installed by Nix in that environment. You +can use the version of Visual Studio Code or Codium you already use, or +also install it using Nix (by adding "vscode" or "vscodium" to the list of +\code{system_pkgs}). For non-interactive use, or to use the environment from the +command line, or from another editor (such as Emacs or Vim), set the \code{ide} +argument to \code{"other"}. We recommend reading the +\code{vignette("e-interactive-use")} for more details. Packages to install from Github must be provided in a list of 4 elements: "package_name", "repo_url", "branch_name" and "commit". This argument can @@ -120,7 +122,13 @@ version 2.2.1 release, then use the Nix revision closest to that date, by setting \code{r_ver = "3.1.0"}, which was the version of R current at the time. This ensures that Nix builds a completely coherent environment. -By default, the nix shell will be configured with \code{"en_US.UTF-8"} for the +Note that installing packages from Git or old versions using the \code{"@"} +notation or local packages, does not leverage Nix's capabilities for +dependency solving. As such, you might have trouble installing these +packages. If that is the case, open an issue on \code{{rix}}'s Github +repository. + +By default, the Nix shell will be configured with \code{"en_US.UTF-8"} for the relevant locale variables (\code{LANG}, \code{LC_ALL}, \code{LC_TIME}, \code{LC_MONETARY}, \code{LC_PAPER}, \code{LC_MEASUREMENT}). This is done to ensure locale reproducibility by default in Nix environments created with \code{rix()}. If @@ -128,18 +136,18 @@ there are good reasons to not stick to the default, you can set your preferred locale variables via \verb{options(rix.nix_locale_variables = list(LANG = "de_CH.UTF-8", <...>)} and the aforementioned locale variable names. -It is possible to use "bleeding_edge" or "frozen_edge" as the value for the -\code{r_ver} argument. This will create an environment with the very latest R -packages. "bleeding_edge" means that every time you will build the +It is possible to use \verb{"bleeding_edge}" or \verb{"frozen_edge}" as the value for +the \code{r_ver} argument. This will create an environment with the very latest +R packages. \verb{"bleeding_edge}" means that every time you will build the environment, the packages will get updated. This is especially useful for environments that need to be constantly updated, for example when -developing a package. In contrast, "frozen_edge" will create an environment -that will remain stable at build time. So if you create a \code{default.nix} -file using "bleeding_edge", each time you build it using \code{nix-build} that -environment will be up-to-date. With "frozen_edge" that environment will be -up-to-date on the date that the \code{default.nix} will be generated, and then -each subsequent call to \code{nix-build} will result in the same environment. We -highly recommend you read the vignette titled +developing a package. In contrast, \verb{"frozen_edge}" will create an +environment that will remain stable at build time. So if you create a +\code{default.nix} file using \verb{"bleeding_edge}", each time you build it using +\code{nix-build} that environment will be up-to-date. With \verb{"frozen_edge}" that +environment will be up-to-date on the date that the \code{default.nix} will be +generated, and then each subsequent call to \code{nix-build} will result in the +same environment. We highly recommend you read the vignette titled "z - Advanced topic: Understanding the rPackages set release cycle and using bleeding edge packages". } \examples{ diff --git a/man/rix_init.Rd b/man/rix_init.Rd index fffdb7cd..4dce4866 100644 --- a/man/rix_init.Rd +++ b/man/rix_init.Rd @@ -12,30 +12,28 @@ rix_init( ) } \arguments{ -\item{project_path}{Character with the folder path to the isolated nix-R project. -Defaults to \code{"."}, which is the current working directory path. If the folder -does not exist yet, it will be created.} +\item{project_path}{Character with the folder path to the isolated nix-R +project. Defaults to \code{"."}, which is the current working directory path. If +the folder does not exist yet, it will be created.} \item{rprofile_action}{Character. Action to take with \code{.Rprofile} file destined for \code{project_path} folder. Possible values include -\code{"create_missing"}, which only writes \code{.Rprofile} if it -does not yet exist (otherwise does nothing); \code{"create_backup"}, which copies -the existing \code{.Rprofile} to a new backup file, generating names with -POSIXct-derived strings that include the time zone information. A new -\code{.Rprofile} file will be written with default code from \code{rix::rix_init()}; -\code{"overwrite"} overwrites the \code{.Rprofile} file if it does exist; \code{"append"} -appends the existing file with code that is tailored to an isolated Nix-R -project setup.} +\code{"create_missing"}, which only writes \code{.Rprofile} if it does not yet exist +(otherwise does nothing) - this is the action set when using \code{rix()} - ; +\code{"create_backup"}, which copies the existing \code{.Rprofile} to a new backup +file, generating names with POSIXct-derived strings that include the time +zone information. A new \code{.Rprofile} file will be written with default code +from \code{rix::rix_init()}; \code{"overwrite"} overwrites the \code{.Rprofile} file if it +does exist; \code{"append"} appends the existing file with code that is tailored +to an isolated Nix-R project setup.} \item{message_type}{Character. Message type, defaults to \code{"simple"}, which gives minimal but sufficient feedback. Other values are currently -\verb{"quiet}, which writes \code{.Rprofile} without message, and -\code{"verbose"}, which displays the mechanisms implemented to achieve fully -controlled R project environments in Nix.} +\verb{"quiet}, which writes \code{.Rprofile} without message, and \code{"verbose"}, +which displays the mechanisms implemented to achieve fully controlled R project environments in Nix.} } \value{ -Nothing, this function only has the side-effect of writing a file -called ".Rprofile" to the specified path. +Nothing, this function only has the side-effect of writing a file called ".Rprofile" to the specified path. } \description{ Creates an isolated project folder for a Nix-R configuration. \code{rix::rix_init()} @@ -53,13 +51,13 @@ The primary goal of \code{rix::rix_init()} is to enhance the computational reproducibility of Nix-R environments during runtime. Concretely, if you already have a system or user library of R packages (if you have R installed through the usual means for your operating system), using \code{rix::rix_init()} -will prevent Nix-R environments to load packages from the user library -which would cause issues. -Notably, no restart is required as environmental variables are set in the current session, in -addition to writing an \code{.Rprofile} file. This is particularly useful to make -\code{\link[=with_nix]{with_nix()}} evaluate custom R functions from any "Nix-to-Nix" or -"System-to-Nix" R setups. It introduces two side-effects that -take effect both in a current or later R session setup: +will prevent Nix-R environments to load packages from the user library which +would cause issues. Notably, no restart is required as environmental +variables are set in the current session, in addition to writing an +\code{.Rprofile} file. This is particularly useful to make \code{\link[=with_nix]{with_nix()}} +evaluate custom R functions from any "Nix-to-Nix" or "System-to-Nix" R +setups. It introduces two side-effects that take effect both in a current or +later R session setup: \enumerate{ \item \strong{Adjusting \code{R_LIBS_USER} path:} By default, the first path of \code{R_LIBS_USER} points to the user library @@ -78,9 +76,9 @@ process. In a host RStudio session not launched via Nix (\code{nix-shell}), the environmental variables from \verb{~/.zshrc} or \verb{~/.bashrc} may not be inherited. Consequently, Nix command line interfaces like \code{nix-shell} -might not be found. The \code{.Rprofile} code written by \code{rix::rix_init()} ensures -that Nix command line programs are accessible by adding the path of the -"bin" directory of the default Nix profile, +might not be found. The \code{.Rprofile} code written by \code{rix::rix_init()} +ensures that Nix command line programs are accessible by adding the path +of the "bin" directory of the default Nix profile, \code{"/nix/var/nix/profiles/default/bin"}, to the \code{PATH} variable in an RStudio R session. } @@ -92,6 +90,12 @@ environments. This init configuration is considered pivotal to enhance the adoption of Nix in the R community, particularly until RStudio in Nixpkgs is packaged for macOS. We recommend calling \code{rix::rix_init()} prior to comparing R code ran between two software environments with \code{rix::with_nix()}. + +\code{rix::rix_init()} is called automatically by \code{rix::rix()} when generating a +\code{default.nix} file, and when called by \code{rix::rix()} will only add the \code{.Rprofile} +if none exists. In case you have a custom \code{.Rprofile} that you wish to keep +using, but also want to benefit from what \code{rix_init()} offers, manually call +it and set the \code{rprofile_action} to \code{"append"}. } \examples{ \dontrun{ diff --git a/man/with_nix.Rd b/man/with_nix.Rd index 7f3af773..9c9895c1 100644 --- a/man/with_nix.Rd +++ b/man/with_nix.Rd @@ -88,7 +88,7 @@ environments. If testing of different sets of environments is necessary, you can easily do so by providing Nix expressions in custom \code{.nix} or \code{default.nix} files in different subfolders of the project. -It is recommended that you use \code{rix_init()} to generate a custom \code{.Rprofile} +\code{rix_init()} is run automatically to generate a custom \code{.Rprofile} file for the subshell in \code{project_dir}. The defaults in that file ensure that only R packages from the Nix store, that are defined in the subshell \code{.nix} file are loaded and system's libraries are excluded. diff --git a/tests/testthat/test-rix.R b/tests/testthat/test-rix.R index c7cb714e..e340ed3d 100644 --- a/tests/testthat/test-rix.R +++ b/tests/testthat/test-rix.R @@ -383,3 +383,41 @@ testthat::test_that("rix(), frozen_edge", { unlink(path_default_nix, recursive = TRUE, force = FALSE) }) }) + + +testthat::test_that("rix(), only one Github package", { + + path_default_nix <- paste0( + tempdir(), paste0(sample(letters, 5), collapse = "") + ) + dir.create(path_default_nix) + path_default_nix <- normalizePath(path_default_nix) + + save_default_nix_test <- function(path_default_nix) { + + rix(r_ver = "latest", + r_pkgs = NULL, + system_pkgs = NULL, + git_pkgs = list(package_name = "lookup", + repo_url = "https://github.com/jimhester/lookup/", + branch_name = "master", + commit = "eba63db477dd2f20153b75e2949eb333a36cccfc"), + ide = "other", + project_path = path_default_nix, + overwrite = TRUE + ) + + file.path(path_default_nix, "default.nix") + } + + testthat::announce_snapshot_file("rix/one_git_default.nix") + + testthat::expect_snapshot_file( + path = save_default_nix_test(path_default_nix), + name = "one_git_default.nix", + ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) +}) diff --git a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd index d6b9622f..fd81d716 100644 --- a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd +++ b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd @@ -52,25 +52,26 @@ Then, add the packages you need to `r_pkgs` and run the script again. Then, buil the environment using `nix-build` again, and drop into it using `nix-shell`. Calling `install.packages()` is a bad idea for several reasons: -- it goes against the idea of defining an environment in a declarative way. If you - were able to add packages using `install.packages()`, your environment would end - up in a state where the `default.nix` definition of the environment and the actual - environment don't match anymore. -- using `install.packages()` will likely simply not work, and if it does, will cause - issues. For example, if you call `install.packages("ggplot2")` from one Nix shell, - it will not install `{ggplot2}` "inside" the Nix shell, but will install it on - your user's system library of packages. This is because the Nix shell cannot be changed - at run-time, and so, R will instead install the packages in the user's library. - This version of `{ggplot2}`, because it is in that system-wide library of packages, - will be available to any other Nix shell. - If you call `install.packages("ggplot2")` again from another Nix shell, say 6 months - later, this will replace the first version of `{ggplot2}` with the latest version. - -Ideally, you should only manage R versions and R packages using Nix, and uninstall -any system-managed version of R and R packages. If you do wish to keep a system-managed -version of R and R packages, we highly recommend that you call `rix_init()` from all -the Nix shells. This should ensure that your Nix projects and your system library of -packages don't interfere with each other. +- it goes against the idea of defining an environment in a declarative way. If + you were able to add packages using `install.packages()`, your environment + would end up in a state where the `default.nix` definition of the environment + and the actual environment don't match anymore. +- using `install.packages()` will likely simply not work, and if it does, will + cause issues. For example, if you call `install.packages("ggplot2")` from one + Nix shell, it will not install `{ggplot2}` "inside" the Nix shell, but will + install it on your user's system library of packages. This is because the Nix + shell cannot be changed at run-time, and so, R will instead install the + packages in the user's library. This version of `{ggplot2}`, because it is in + that system-wide library of packages, will be available to any other Nix + shell. If you call `install.packages("ggplot2")` again from another Nix shell, + say 6 months later, this will replace the first version of `{ggplot2}` with + the latest version. + +Ideally, you should only manage R versions and R packages using Nix, and +uninstall any system-managed version of R and R packages. If you do wish to keep +a system-managed version of R and R packages, we highly recommend that you call +`rix_init()` from all the Nix shells. This should ensure that your Nix projects +and your system library of packages don't interfere with each other. ## Installing old packages archived on CRAN From de04bee5a4a5fc82216a1bcc252d618035a8a2e4 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 11:58:49 +0200 Subject: [PATCH 07/21] documentation --- tests/testthat/_snaps/rix/one_git_default.nix | 51 +++++++++++++++++++ ...alling-r-packages-in-a-nix-environment.Rmd | 15 +++++- ...ling-packages-with-remote-dependencies.Rmd | 10 +++- ...oducible-analytical-pipelines-with-nix.Rmd | 10 +++- 4 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 tests/testthat/_snaps/rix/one_git_default.nix diff --git a/tests/testthat/_snaps/rix/one_git_default.nix b/tests/testthat/_snaps/rix/one_git_default.nix new file mode 100644 index 00000000..b1c3a1b7 --- /dev/null +++ b/tests/testthat/_snaps/rix/one_git_default.nix @@ -0,0 +1,51 @@ + +let + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; + + git_archive_pkgs = [ + (pkgs.rPackages.buildRPackage { + name = "lookup"; + src = pkgs.fetchgit { + url = "https://github.com/jimhester/lookup/"; + branchName = "master"; + rev = "eba63db477dd2f20153b75e2949eb333a36cccfc"; + sha256 = "sha256-arl7LVxL8xGUW3LhuDCSUjcfswX0rdofL/7v8Klw8FM="; + }; + propagatedBuildInputs = builtins.attrValues { + inherit (pkgs.rPackages) + gh + memoise + Rcpp + codetools + crayon + rex + highlite + jsonlite + rstudioapi + withr + httr; + }; + }) + ]; + + system_packages = builtins.attrValues { + inherit (pkgs) + R + glibcLocales + nix; + }; + +in + +pkgs.mkShell { + LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; + LANG = "en_US.UTF-8"; + LC_ALL = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + + buildInputs = [ git_archive_pkgs system_packages ]; + +} diff --git a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd index fd81d716..0856550f 100644 --- a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd +++ b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd @@ -80,7 +80,10 @@ archived on CRAN: ```{r parsermd-chunk-1} -path_default_nix <- tempdir() +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) rix(r_ver = "4.2.1", r_pkgs = c("dplyr@0.8.0", "janitor@1.0.0"), @@ -110,6 +113,11 @@ It is also possible to install packages from Github: ```{r parsermd-chunk-3} +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) + rix(r_ver = "4.2.1", r_pkgs = c("dplyr", "janitor"), git_pkgs = list( @@ -162,6 +170,11 @@ from GitHub: ```{r parsermd-chunk-5} +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) + rix(r_ver = "4.2.1", r_pkgs = c("dplyr", "janitor", "AER@1.2-8"), git_pkgs = list( diff --git a/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd b/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd index 53d0b33a..b6461981 100644 --- a/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd +++ b/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd @@ -46,7 +46,10 @@ the following `rix::rix()` call: ```{r parsermd-chunk-1} -path_default_nix <- tempdir() +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) rix(r_ver = "latest", r_pkgs = NULL, @@ -89,6 +92,11 @@ however, because it never got released on CRAN. Doing so is fairly easy: first, create a new expression using `{rix}` to install `{highlite}`: ``` +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) + rix(r_ver = "latest", r_pkgs = NULL, system_pkgs = NULL, diff --git a/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd b/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd index 9d6f8444..b26a4849 100644 --- a/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd +++ b/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd @@ -34,7 +34,10 @@ you could have used to build that environment: ```{r parsermd-chunk-1} -path_default_nix <- tempdir() +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) rix(r_ver = "4.2.2", r_pkgs = c("targets", "tarchetypes", "rmarkdown"), @@ -77,6 +80,11 @@ add a *Shell-hook* to the generated `default.nix` file: ```{r parsermd-chunk-3, eval = FALSE} +path_default_nix <- paste0( + tempdir(), "repo", + paste0(sample(letters, 5), collapse = "") +) + rix(r_ver = "4.2.2", r_pkgs = c("targets", "tarchetypes", "rmarkdown"), system_pkgs = NULL, From 04fda648e789d3c5fdba0460e35a06267831c837 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 14:15:30 +0200 Subject: [PATCH 08/21] added message_type --- R/rix.R | 30 ++++++++++++++++++++++++------ tests/testthat/test-rix.R | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/R/rix.R b/R/rix.R index 5c741e9b..eee8500e 100644 --- a/R/rix.R +++ b/R/rix.R @@ -42,6 +42,10 @@ #' `default.nix` file in the specified path. #' @param print Logical, defaults to FALSE. If TRUE, print `default.nix` to #' console. +#' @param message_type Character. Message type, defaults to `"simple"`, which +#' gives minimal but sufficient feedback. Other values are currently +#' `"quiet`, which generates the files without message, and `"verbose"`, +#' displays all the messages. #' @param shell_hook Character of length 1, defaults to `NULL`. Commands added #' to the `shellHook` variable are executed when the Nix shell starts. So by #' default, using `nix-shell default.nix` will start a specific program, @@ -128,6 +132,7 @@ #' project_path = path_default_nix, #' overwrite = TRUE, #' print = TRUE, +#' message_type = "simple" #' shell_hook = NULL #' ) #' } @@ -141,9 +146,14 @@ rix <- function(r_ver = "latest", project_path = ".", overwrite = FALSE, print = FALSE, + message_type = "verbose", shell_hook = NULL) { - if (r_ver %in% c("bleeding_edge", "frozen_edge")) { + message_type <- match.arg(message_type, + choices = c("quiet", "simple", "verbose") + ) + + if (!(message_type %in% c("simple", "quiet")) & r_ver %in% c("bleeding_edge", "frozen_edge")) { warning( "You chose 'bleeding_edge' or 'frozen_edge' as the value for `r_ver`. Please read the vignette @@ -152,13 +162,13 @@ before continuing." ) } - if(r_ver %in% available_r() & r_ver != "latest" & r_ver <= "4.1.1"){ + if(message_type != "quiet" & r_ver %in% available_r() & r_ver != "latest" & r_ver <= "4.1.1"){ warning( "You are generating an expression for an older version of R.\n To use this environment, you should directly use `nix-shell` and not try to build it first using `nix-build`." ) } - if(r_ver == "4.4.0"){ + if(message_type != "quiet" & r_ver == "4.4.0"){ warning( "You chose '4.4.0' as the R version, however this version is not available in nixpkgs. The generated expression will thus install R version 4.4.1." ) @@ -173,7 +183,7 @@ before continuing." rserver = "rstudioServerWrapper" ) - if (Sys.info()["sysname"] == "Darwin" & ide == "rstudio") { + if (message_type != "quiet" & Sys.info()["sysname"] == "Darwin" & ide == "rstudio") { warning( "Your detected operating system is macOS, and you chose 'rstudio' as the IDE. Please note that 'rstudio' is not @@ -277,10 +287,18 @@ for more details." if (!file.exists(default.nix_path) || overwrite) { writeLines(default.nix, default.nix_path) + rix_init(project_path = project_path, rprofile_action = "create_missing", - message_type = "quiet") - cat("\nSuccessfully generated `default.nix` and `.Rprofile`\n") + # 'verbose' is too chatty for rix() + # hence why it's transformed to "simple" + message_type = ifelse(message_type == "verbose", + "simple", message_type)) + + if(message_type != "quiet"){ + message("\n\n### Successfully generated `default.nix` and `.Rprofile` ###\n\n") + } + } else { project_path <- if(project_path == ".") { "current folder" diff --git a/tests/testthat/test-rix.R b/tests/testthat/test-rix.R index e340ed3d..4c6ec6ff 100644 --- a/tests/testthat/test-rix.R +++ b/tests/testthat/test-rix.R @@ -421,3 +421,30 @@ testthat::test_that("rix(), only one Github package", { unlink(path_default_nix, recursive = TRUE, force = TRUE) }) }) + + +testthat::test_that("rix(), conclusion message", { + + path_default_nix <- paste0( + tempdir(), paste0(sample(letters, 5), collapse = "") + ) + dir.create(path_default_nix) + path_default_nix <- normalizePath(path_default_nix) + + save_default_nix_test <- function(path_default_nix) { + + rix(r_ver = "latest", + ide = "other", + project_path = path_default_nix, + message_type = "simple", + overwrite = TRUE + ) + + file.path(path_default_nix, "default.nix") + } + + testthat::expect_message( + save_default_nix_test(path_default_nix), + regexp = "Successfully" + ) +}) From dfb32fd940dd332cd087c204c744700ed600a40f Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 15:15:56 +0200 Subject: [PATCH 09/21] documentation --- .Rbuildignore | 2 + man/rix.Rd | 7 + tests/testthat/test-rix.R | 4 + ...-up-and-using-rix-on-linux-and-windows.Rmd | 8 +- ...to-build-project-specific-environments.Rmd | 95 ++++- ...alling-r-packages-in-a-nix-environment.Rmd | 352 ++++++++++++++++-- ...-texlive-packages-in-a-nix-environment.Rmd | 102 ++++- vignettes/e-interactive-use.Rmd | 17 +- ...n-environment-for-literate-programming.Rmd | 11 +- ...ling-packages-with-remote-dependencies.Rmd | 15 +- ...oducible-analytical-pipelines-with-nix.Rmd | 30 +- 11 files changed, 556 insertions(+), 87 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 4cf91ffe..ea5f8885 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -22,3 +22,5 @@ create_dev_env.R ^.*.tar.gz ^\.pre-commit-config\.yaml$ ^data-raw$ +.envrc +.direnv \ No newline at end of file diff --git a/man/rix.Rd b/man/rix.Rd index 1812c539..ed33b607 100644 --- a/man/rix.Rd +++ b/man/rix.Rd @@ -15,6 +15,7 @@ rix( project_path = ".", overwrite = FALSE, print = FALSE, + message_type = "verbose", shell_hook = NULL ) } @@ -66,6 +67,11 @@ the folder does not exist, it will be created.} \item{print}{Logical, defaults to FALSE. If TRUE, print \code{default.nix} to console.} +\item{message_type}{Character. Message type, defaults to \code{"simple"}, which +gives minimal but sufficient feedback. Other values are currently +\verb{"quiet}, which generates the files without message, and \code{"verbose"}, +displays all the messages.} + \item{shell_hook}{Character of length 1, defaults to \code{NULL}. Commands added to the \code{shellHook} variable are executed when the Nix shell starts. So by default, using \verb{nix-shell default.nix} will start a specific program, @@ -164,6 +170,7 @@ rix( project_path = path_default_nix, overwrite = TRUE, print = TRUE, + message_type = "simple" shell_hook = NULL ) } diff --git a/tests/testthat/test-rix.R b/tests/testthat/test-rix.R index 4c6ec6ff..d56f98f4 100644 --- a/tests/testthat/test-rix.R +++ b/tests/testthat/test-rix.R @@ -447,4 +447,8 @@ testthat::test_that("rix(), conclusion message", { save_default_nix_test(path_default_nix), regexp = "Successfully" ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) diff --git a/vignettes/b1-setting-up-and-using-rix-on-linux-and-windows.Rmd b/vignettes/b1-setting-up-and-using-rix-on-linux-and-windows.Rmd index 0a7d205f..60535335 100644 --- a/vignettes/b1-setting-up-and-using-rix-on-linux-and-windows.Rmd +++ b/vignettes/b1-setting-up-and-using-rix-on-linux-and-windows.Rmd @@ -141,7 +141,7 @@ nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/m This should immediately start an R session inside your terminal. You can now run something like this: -``` +```{r, eval = F} rix(r_ver = "latest", r_pkgs = c("dplyr", "ggplot2"), system_pkgs = NULL, @@ -162,10 +162,10 @@ More details about managing project-specific `default.nix` are detailled in the vignette `vignette("d1-installing-r-packages-in-a-nix-environment")` and `vignette("d2-installing-system-tools-and-texlive-packages-in-a-nix-environment")`. -You could also include `{rix}` in your project-specific environments, by generating -a `default.nix` like so: +You could also include `{rix}` in your project-specific environments, by +generating a `default.nix` like so: -``` +```{r, eval = F} rix(r_ver = "latest", r_pkgs = NULL, git_pkgs = list(package_name = "rix", diff --git a/vignettes/c-using-rix-to-build-project-specific-environments.Rmd b/vignettes/c-using-rix-to-build-project-specific-environments.Rmd index 3f8324d2..af65ecb0 100644 --- a/vignettes/c-using-rix-to-build-project-specific-environments.Rmd +++ b/vignettes/c-using-rix-to-build-project-specific-environments.Rmd @@ -50,7 +50,7 @@ file. You need to provide the following inputs to `rix()`: Run the following command to generate the right `default.nix` file: -```{r parsermd-chunk-1} +```{r, eval = F} path_default_nix <- tempdir() rix(r_ver = "latest", @@ -61,6 +61,51 @@ rix(r_ver = "latest", project_path = path_default_nix, overwrite = TRUE, print = TRUE) +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "12a9c0004bc987afb1ff511ebb97b67497a68e22", +#> # > r_pkgs = c("dplyr", +#> # > "ggplot2"), +#> # > system_pkgs = NULL, +#> # > git_pkgs = NULL, +#> # > ide = "code", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE, +#> # > print = TRUE) +#> # It uses nixpkgs' revision 12a9c0004bc987afb1ff511ebb97b67497a68e22 for reproducibility purposes +#> # which will install R version latest. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; +#> +#> rpkgs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> ggplot2 +#> languageserver; +#> }; +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ rpkgs system_packages ]; +#> +#> } ``` To start using this environment, open a terminal in the folder containing @@ -114,9 +159,51 @@ rix(r_ver = "4.2.1", The file looks like this: - -```{r parsermd-chunk-3, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a", +#> # > r_pkgs = c("dplyr", +#> # > "janitor"), +#> # > system_pkgs = c("quarto"), +#> # > git_pkgs = NULL, +#> # > ide = "other", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE) +#> # It uses nixpkgs' revision 79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a for reproducibility purposes +#> # which will install R version 4.2.1. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a.tar.gz") {}; +#> +#> rpkgs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> janitor; +#> }; +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> quarto +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ rpkgs system_packages ]; +#> +#> } ``` The first line is quite important, as it shows which *revision* of `nixpkgs` is diff --git a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd index 0856550f..845fff2d 100644 --- a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd +++ b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd @@ -78,12 +78,8 @@ and your system library of packages don't interfere with each other. It is possible to install an arbitrary version of a package that has been archived on CRAN: - -```{r parsermd-chunk-1} -path_default_nix <- paste0( - tempdir(), "repo", - paste0(sample(letters, 5), collapse = "") -) +```{r, eval = F} +path_default_nix <- tempdir() rix(r_ver = "4.2.1", r_pkgs = c("dplyr@0.8.0", "janitor@1.0.0"), @@ -94,8 +90,90 @@ rix(r_ver = "4.2.1", overwrite = TRUE) ``` -```{r parsermd-chunk-2, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a", +#> # > r_pkgs = c("dplyr@0.8.0", +#> # > "janitor@1.0.0"), +#> # > system_pkgs = NULL, +#> # > git_pkgs = NULL, +#> # > ide = "other", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE) +#> # It uses nixpkgs' revision 79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a for reproducibility purposes +#> # which will install R version 4.2.1. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a.tar.gz") {}; +#> +#> git_archive_pkgs = [ +#> (pkgs.rPackages.buildRPackage { +#> name = "dplyr"; +#> src = pkgs.fetchzip { +#> url = "https://cran.r-project.org/src/contrib/Archive/dplyr/dplyr_0.8.0.tar.gz"; +#> sha256 = "sha256-f30raalLd9KoZKZSxeTN71PG6BczXRIiP6g7EZeH09U="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> assertthat +#> glue +#> magrittr +#> pkgconfig +#> R6 +#> Rcpp +#> rlang +#> tibble +#> tidyselect +#> BH +#> plogr; +#> }; +#> }) +#> +#> +#> (pkgs.rPackages.buildRPackage { +#> name = "janitor"; +#> src = pkgs.fetchzip { +#> url = "https://cran.r-project.org/src/contrib/Archive/janitor/janitor_1.0.0.tar.gz"; +#> sha256 = "sha256-3NJomE/CNbOZ+ohuVZJWe2n1RVGUm8x8a0A0qzLmdN4="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> tidyr +#> snakecase +#> magrittr +#> purrr +#> rlang; +#> }; +#> }) +#> ]; +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ git_archive_pkgs system_packages ]; +#> +#> } +``` + +```{r, include = FALSE} +unlink(path_default_nix, recursive = TRUE, force = TRUE) ``` The above expression will install R version 4.2.1, and `{dplyr}` at version @@ -111,12 +189,8 @@ particular package. It is also possible to install packages from Github: - -```{r parsermd-chunk-3} -path_default_nix <- paste0( - tempdir(), "repo", - paste0(sample(letters, 5), collapse = "") -) +```{r, eval = F} +path_default_nix <- tempdir() rix(r_ver = "4.2.1", r_pkgs = c("dplyr", "janitor"), @@ -137,9 +211,110 @@ rix(r_ver = "4.2.1", ``` ```{r parsermd-chunk-4, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a", +#> # > r_pkgs = c("dplyr", +#> # > "janitor"), +#> # > git_pkgs = list(list(package_name = "housing", +#> # > repo_url = "https://github.com/rap4all/housing/", +#> # > branch_name = "fusen", +#> # > commit = "1c860959310b80e67c41f7bbdc3e84cef00df18e"), +#> # > list(package_name = "fusen", +#> # > repo_url = "https://github.com/ThinkR-open/fusen", +#> # > branch_name = "main", +#> # > commit = "d617172447d2947efb20ad6a4463742b8a5d79dc")), +#> # > ide = "other", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE) +#> # It uses nixpkgs' revision 79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a for reproducibility purposes +#> # which will install R version 4.2.1. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a.tar.gz") {}; +#> +#> rpkgs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> janitor; +#> }; +#> +#> git_archive_pkgs = [ +#> (pkgs.rPackages.buildRPackage { +#> name = "housing"; +#> src = pkgs.fetchgit { +#> url = "https://github.com/rap4all/housing/"; +#> branchName = "fusen"; +#> rev = "1c860959310b80e67c41f7bbdc3e84cef00df18e"; +#> sha256 = "sha256-s4KGtfKQ7hL0sfDhGb4BpBpspfefBN6hf+XlslqyEn4="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> ggplot2 +#> janitor +#> purrr +#> readxl +#> rlang +#> rvest +#> stringr +#> tidyr; +#> }; +#> }) +#> +#> +#> (pkgs.rPackages.buildRPackage { +#> name = "fusen"; +#> src = pkgs.fetchgit { +#> url = "https://github.com/ThinkR-open/fusen"; +#> branchName = "main"; +#> rev = "d617172447d2947efb20ad6a4463742b8a5d79dc"; +#> sha256 = "sha256-TOHA1ymLUSgZMYIA1a2yvuv0799svaDOl3zOhNRxcmw="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> attachment +#> cli +#> desc +#> devtools +#> glue +#> here +#> magrittr +#> parsermd +#> roxygen2 +#> stringi +#> tibble +#> tidyr +#> usethis +#> yaml; +#> }; +#> }) +#> ]; +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ git_archive_pkgs rpkgs system_packages ]; +#> +#> } ``` + This will install two packages from Github: the `{housing}` package and more specifically the code as it is in the `fusen` branch. The commit is also provided, to pin the exact version of the package needed. The `{fusen}` package @@ -148,32 +323,28 @@ is also installed, from the main branch at commit `d617172447d`. ## Installing local archives It is also possible to install packages from a local `tar.gz` file. For this, -place the package in the same folder where the `default.nix` will be generated, and -write something like this: +place the package in the same folder where the `default.nix` will be generated, +and write something like this: -``` +```{r, eval = F} rix(r_ver = '4.3.1', local_pkgs = c('chronicler_0.2.1.tar.gz', 'knitr_1.43.tar.gz'), overwrite = TRUE) ``` -This assumes that both `chronicler_0.2.1.tar.gz` and `knitr_1.43.tar.gz` have been -downloaded beforehand. If you want to include a local package that you are developing, -make sure to first build it using `devtools::build()` to build the `.tar.gz` archive, but -if you can, consider uploading the source code to your package on Github and installing -it from Github instead. +This assumes that both `chronicler_0.2.1.tar.gz` and `knitr_1.43.tar.gz` have +been downloaded beforehand. If you want to include a local package that you are +developing, make sure to first build it using `devtools::build()` to build the +`.tar.gz` archive, but if you can, consider uploading the source code to your +package on Github and installing it from Github instead. ## A complete example This example shows how to install packages from CRAN, from the CRAN archives and from GitHub: - -```{r parsermd-chunk-5} -path_default_nix <- paste0( - tempdir(), "repo", - paste0(sample(letters, 5), collapse = "") -) +```{r, eval = F} +path_default_nix <- tempdir() rix(r_ver = "4.2.1", r_pkgs = c("dplyr", "janitor", "AER@1.2-8"), @@ -193,9 +364,128 @@ rix(r_ver = "4.2.1", ``` -```{r parsermd-chunk-6, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") ``` +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a", +#> # > r_pkgs = c("dplyr", +#> # > "janitor", +#> # > "AER@1.2-8"), +#> # > git_pkgs = list(list(package_name = "housing", +#> # > repo_url = "https://github.com/rap4all/housing/", +#> # > branch_name = "fusen", +#> # > commit = "1c860959310b80e67c41f7bbdc3e84cef00df18e"), +#> # > list(package_name = "fusen", +#> # > repo_url = "https://github.com/ThinkR-open/fusen", +#> # > branch_name = "main", +#> # > commit = "d617172447d2947efb20ad6a4463742b8a5d79dc")), +#> # > ide = "other", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE) +#> # It uses nixpkgs' revision 79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a for reproducibility purposes +#> # which will install R version 4.2.1. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a.tar.gz") {}; +#> +#> rpkgs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> janitor; +#> }; +#> +#> git_archive_pkgs = [ +#> (pkgs.rPackages.buildRPackage { +#> name = "housing"; +#> src = pkgs.fetchgit { +#> url = "https://github.com/rap4all/housing/"; +#> branchName = "fusen"; +#> rev = "1c860959310b80e67c41f7bbdc3e84cef00df18e"; +#> sha256 = "sha256-s4KGtfKQ7hL0sfDhGb4BpBpspfefBN6hf+XlslqyEn4="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> dplyr +#> ggplot2 +#> janitor +#> purrr +#> readxl +#> rlang +#> rvest +#> stringr +#> tidyr; +#> }; +#> }) +#> +#> +#> (pkgs.rPackages.buildRPackage { +#> name = "fusen"; +#> src = pkgs.fetchgit { +#> url = "https://github.com/ThinkR-open/fusen"; +#> branchName = "main"; +#> rev = "d617172447d2947efb20ad6a4463742b8a5d79dc"; +#> sha256 = "sha256-TOHA1ymLUSgZMYIA1a2yvuv0799svaDOl3zOhNRxcmw="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> attachment +#> cli +#> desc +#> devtools +#> glue +#> here +#> magrittr +#> parsermd +#> roxygen2 +#> stringi +#> tibble +#> tidyr +#> usethis +#> yaml; +#> }; +#> }) +#> +#> (pkgs.rPackages.buildRPackage { +#> name = "AER"; +#> src = pkgs.fetchzip { +#> url = "https://cran.r-project.org/src/contrib/Archive/AER/AER_1.2-8.tar.gz"; +#> sha256 = "sha256-OqxXcnUX/2C6wfD5fuNayc8OU+mstI3tt4eBVGQZ2S0="; +#> }; +#> propagatedBuildInputs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> car +#> lmtest +#> sandwich +#> survival +#> zoo +#> Formula; +#> }; +#> }) +#> ]; +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ git_archive_pkgs rpkgs system_packages ]; +#> +#> } +``` + The next vignette, `vignette("d2-installing-system-tools-and-texlive-packages-in-a-nix-environment")`, diff --git a/vignettes/d2-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd b/vignettes/d2-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd index 6c91995f..dcc0a18f 100644 --- a/vignettes/d2-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd +++ b/vignettes/d2-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd @@ -49,8 +49,7 @@ latest version of R. The R `{quarto}` package is also installed, as well as the `quarto` command line tool (required to edit Quarto documents from R using the `{quarto}` package) and git: - -```{r parsermd-chunk-1} +```{r, eval = F} path_default_nix <- tempdir() rix(r_ver = "latest", @@ -63,7 +62,50 @@ rix(r_ver = "latest", ``` ```{r parsermd-chunk-2, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "12a9c0004bc987afb1ff511ebb97b67497a68e22", +#> # > r_pkgs = c("quarto"), +#> # > system_pkgs = c("quarto", +#> # > "git"), +#> # > git_pkgs = NULL, +#> # > ide = "other", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE) +#> # It uses nixpkgs' revision 12a9c0004bc987afb1ff511ebb97b67497a68e22 for reproducibility purposes +#> # which will install R version latest. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; +#> +#> rpkgs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> quarto; +#> }; +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> quarto +#> git +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ rpkgs system_packages ]; +#> +#> } ``` You can look for all the available software @@ -72,7 +114,6 @@ Simply look for the right package name, and add it to the `system_pkgs` argument of `rix()`. If you have trouble finding something, don’t hesitate to [open an issue ](https://github.com/b-rodrigues/rix/issues) and ask for support! - ## Installing TexLive packages Whether you use Quarto, Rmarkdown, or Sweave, literate programming with R @@ -81,8 +122,7 @@ a minimalist TexLive distribution and then add the packages that you require as you go. The basic use is to simply add a TexLive package to the `tex_pkgs` argument of `rix()` like this: - -```{r parsermd-chunk-3} +```{r, eval = F} path_default_nix <- tempdir() rix(r_ver = "latest", @@ -93,6 +133,55 @@ rix(r_ver = "latest", project_path = path_default_nix, overwrite = TRUE, print = TRUE) +#> # This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +#> # with following call: +#> # >rix(r_ver = "12a9c0004bc987afb1ff511ebb97b67497a68e22", +#> # > r_pkgs = c("quarto"), +#> # > system_pkgs = "quarto", +#> # > tex_pkgs = c("amsmath"), +#> # > ide = "other", +#> # > project_path = path_default_nix, +#> # > overwrite = TRUE, +#> # > print = TRUE) +#> # It uses nixpkgs' revision 12a9c0004bc987afb1ff511ebb97b67497a68e22 for reproducibility purposes +#> # which will install R version latest. +#> # Report any issues to https://github.com/b-rodrigues/rix +#> let +#> pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; +#> +#> rpkgs = builtins.attrValues { +#> inherit (pkgs.rPackages) +#> quarto; +#> }; +#> +#> tex = (pkgs.texlive.combine { +#> inherit (pkgs.texlive) +#> scheme-small +#> amsmath; +#> }); +#> +#> system_packages = builtins.attrValues { +#> inherit (pkgs) +#> quarto +#> R +#> glibcLocales +#> nix; +#> }; +#> +#> in +#> +#> pkgs.mkShell { +#> LOCALE_ARCHIVE = if pkgs.system == "x86_64-linux" then "${pkgs.glibcLocales}/lib/locale/locale-archive" else ""; +#> LANG = "en_US.UTF-8"; +#> LC_ALL = "en_US.UTF-8"; +#> LC_TIME = "en_US.UTF-8"; +#> LC_MONETARY = "en_US.UTF-8"; +#> LC_PAPER = "en_US.UTF-8"; +#> LC_MEASUREMENT = "en_US.UTF-8"; +#> +#> buildInputs = [ rpkgs tex system_packages ]; +#> +#> } ``` @@ -101,7 +190,6 @@ This will automically add the *small* TexLive distribution available through environments for literate programming, refer to the vignette `vignette("z-advanced-topic-building-an-environment-for-literate-programming")`. - ## Installing IDEs Environments built with Nix are not completely cut off from the rest of your diff --git a/vignettes/e-interactive-use.Rmd b/vignettes/e-interactive-use.Rmd index 6fa6541b..9fa25cb4 100644 --- a/vignettes/e-interactive-use.Rmd +++ b/vignettes/e-interactive-use.Rmd @@ -59,19 +59,6 @@ like `C:\Users\Billy\Documents\kmeans`). For example, here is how you could use `{rix}` to generate the `default.nix` for this environment: -```{r parsermd-chunk-1, include = FALSE} -path_default_nix <- tempdir() - -rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "rstudio", - project_path = path_default_nix, - overwrite = TRUE, - print = TRUE) -``` - ```{r parsermd-chunk-2, eval = FALSE} library(rix) @@ -190,13 +177,13 @@ environment, since these are globally defined at the level of your system. This means that to work on a project using VS Code, you would use a call to `rix()` like so: -``` +```{r, eval = FALSE} rix(r_ver = "latest", r_pkgs = c("dplyr", "ggplot2"), system_pkgs = NULL, git_pkgs = NULL, ide = "code", - project_path = ".", + project_path = ".", overwrite = TRUE) ``` diff --git a/vignettes/z-advanced-topic-building-an-environment-for-literate-programming.Rmd b/vignettes/z-advanced-topic-building-an-environment-for-literate-programming.Rmd index 22ca1286..672276c1 100644 --- a/vignettes/z-advanced-topic-building-an-environment-for-literate-programming.Rmd +++ b/vignettes/z-advanced-topic-building-an-environment-for-literate-programming.Rmd @@ -28,7 +28,6 @@ this, which will also be ideal for interactive development (writing the doc). The second section will discuss a way to build the document in a completely reproducible manner once it's done. - ## Starting with the basics (simple but not entirely reproducible) This approach will not be the most optimal, but it will be the simplest. We will @@ -42,10 +41,10 @@ add both of them to the `r_pkgs` and `system_pkgs` of arguments of `{rix}`. Because we want to compile a PDF, we also need to have `texlive` installed, as well as some LaTeX packages. For this, we use the `tex_pkgs` argument: - -```{r parsermd-chunk-1} +```{r, eval = F} path_default_nix <- tempdir() + rix(r_ver = "4.3.1", r_pkgs = c("quarto"), system_pkgs = "quarto", @@ -106,8 +105,7 @@ So there's an R chunk in `template.qmd` that uses the `{MASS}` package. Change `build_env.R` to generate a new `default.nix` file that will now add `{MASS}` to the environment when built: - -```{r parsermd-chunk-2} +```{r, eval = FALSE} rix(r_ver = "4.3.1", r_pkgs = c("quarto", "MASS"), system_pkgs = "quarto", @@ -143,7 +141,7 @@ easier way to list the dependencies and requirements of a LaTeX document. This is what the final script to build the environment looks like: -```{r parsermd-chunk-3} +```{r, eval = FALSE} rix(r_ver = "4.3.1", r_pkgs = c("quarto", "MASS"), system_pkgs = "quarto", @@ -352,7 +350,6 @@ PDF in your PDF viewer application (on Linux at least): xdg-open $(readlink result)/template.pdf ``` - ## Conclusion This vignette showed two approaches, both have their merits: the first approach diff --git a/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd b/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd index b6461981..0231a264 100644 --- a/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd +++ b/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd @@ -45,11 +45,8 @@ Fortran. To create a reproducible development environment that makes the following `rix::rix()` call: -```{r parsermd-chunk-1} -path_default_nix <- paste0( - tempdir(), "repo", - paste0(sample(letters, 5), collapse = "") -) +```{r, include = F } +path_default_nix <- tempdir() rix(r_ver = "latest", r_pkgs = NULL, @@ -71,7 +68,6 @@ Trying to build this environment will fail with following error message: error: attribute 'highlite' missing ``` - ## Building remote dependencies `{highlite}` is a dependency of [{lookup}](https://github.com/jimhester/lookup) @@ -91,11 +87,8 @@ they are also available through `nixpkgs`. We have to deal with `{highlite}` however, because it never got released on CRAN. Doing so is fairly easy: first, create a new expression using `{rix}` to install `{highlite}`: -``` -path_default_nix <- paste0( - tempdir(), "repo", - paste0(sample(letters, 5), collapse = "") -) +```{r, eval = F} +path_default_nix <- tempdir() rix(r_ver = "latest", r_pkgs = NULL, diff --git a/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd b/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd index b26a4849..a11ba0b4 100644 --- a/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd +++ b/vignettes/z-advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd @@ -32,8 +32,7 @@ Suppose that you've used `{targets}` to build a pipeline for a project and that you did so using a tailor-made Nix environment. Here is the call to `rix()` that you could have used to build that environment: - -```{r parsermd-chunk-1} +```{r, include = F} path_default_nix <- paste0( tempdir(), "repo", paste0(sample(letters, 5), collapse = "") @@ -52,13 +51,32 @@ rix(r_ver = "4.2.2", ``` -This call to `rix()` generates the following `default.nix` file: +```{r, eval = F} +path_default_nix <- tempdir() + +rix(r_ver = "4.2.2", + r_pkgs = c("targets", "tarchetypes", "rmarkdown"), + system_pkgs = NULL, + git_pkgs = list(package_name = "housing", + repo_url = "https://github.com/rap4all/housing/", + branch_name = "fusen", + commit = "1c860959310b80e67c41f7bbdc3e84cef00df18e"), + ide = "other", + project_path = path_default_nix, + overwrite = TRUE) + +``` +This call to `rix()` generates the following `default.nix` file: ```{r parsermd-chunk-2, echo = F} cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") ``` +```{r, include = FALSE} +unlink(path_default_nix, recursive = TRUE, force = TRUE) +``` + The environment that gets built from this `default.nix` file contains R version 4.2.2, the `{targets}` and `{tarchetypes}` packages, as well as the `{housing}` packages, which is a package that is hosted on GitHub only with some data and @@ -78,12 +96,8 @@ cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'target If you wish to run the pipeline whenever you drop into the Nix shell, you could add a *Shell-hook* to the generated `default.nix` file: - ```{r parsermd-chunk-3, eval = FALSE} -path_default_nix <- paste0( - tempdir(), "repo", - paste0(sample(letters, 5), collapse = "") -) +path_default_nix <- tempdir() rix(r_ver = "4.2.2", r_pkgs = c("targets", "tarchetypes", "rmarkdown"), From 93a7fb98ae0cefb2b6a496a8240bbfe7875b7deb Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 15:25:16 +0200 Subject: [PATCH 10/21] removed old code --- vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd | 3 --- 1 file changed, 3 deletions(-) diff --git a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd index 845fff2d..ec21e259 100644 --- a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd +++ b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd @@ -172,9 +172,6 @@ rix(r_ver = "4.2.1", #> } ``` -```{r, include = FALSE} -unlink(path_default_nix, recursive = TRUE, force = TRUE) -``` The above expression will install R version 4.2.1, and `{dplyr}` at version 0.8.0 and `{janitor}` at version 1.0.0. This can be useful, especially for From 2b62be410ba39cb22d181f94a56ebf15701de932 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 17:09:54 +0200 Subject: [PATCH 11/21] check for existence of .Rprofile --- R/rix.R | 31 ++++++--- tests/testthat/test-nix_build.R | 10 ++- tests/testthat/test-rix.R | 109 +++++++++++++++++++++----------- tests/testthat/test-rix_init.R | 4 ++ tests/testthat/test-with_nix.R | 36 +++++------ 5 files changed, 117 insertions(+), 73 deletions(-) diff --git a/R/rix.R b/R/rix.R index eee8500e..f4041c75 100644 --- a/R/rix.R +++ b/R/rix.R @@ -207,12 +207,19 @@ for more details." paste0(project_path, "/default.nix") } + .Rprofile_path <- if (project_path == ".") { + ".Rprofile" + } else { + paste0(project_path, "/.Rprofile") + } + # Find url to use # In case of bleeding or frozen edge, the rstats-on-nix/nixpkgs # fork is used. Otherwise, upstream NixOS/nixpkgs nix_repo <- make_nixpkgs_url(r_ver) default.nix_path <- file.path(default.nix_path) + .Rprofile_path <- file.path(.Rprofile_path) rix_call <- match.call() @@ -288,16 +295,22 @@ for more details." if (!file.exists(default.nix_path) || overwrite) { writeLines(default.nix, default.nix_path) - rix_init(project_path = project_path, - rprofile_action = "create_missing", - # 'verbose' is too chatty for rix() - # hence why it's transformed to "simple" - message_type = ifelse(message_type == "verbose", - "simple", message_type)) + if(!file.exists(.Rprofile_path)){ + rix_init(project_path = project_path, + rprofile_action = "create_missing", + # 'verbose' is too chatty for rix() + # hence why it's transformed to "simple" + message_type = ifelse(message_type == "verbose", + "simple", message_type)) + + if(message_type != "quiet"){ + message("\n\n### Successfully generated `default.nix` and `.Rprofile` ###\n\n") + } - if(message_type != "quiet"){ - message("\n\n### Successfully generated `default.nix` and `.Rprofile` ###\n\n") - } + } else if(all(!grepl("File generated by `rix::rix_init()", + readLines(.Rprofile_path)))){ + warning("\n\n### .Rprofile file already exists. You may want to call rix_init(profile_action = 'append') manually to ensure correct functioning of your Nix environment. ###\n\n") + } } else { project_path <- if(project_path == ".") { diff --git a/tests/testthat/test-nix_build.R b/tests/testthat/test-nix_build.R index d82c6189..4c756f40 100644 --- a/tests/testthat/test-nix_build.R +++ b/tests/testthat/test-nix_build.R @@ -11,12 +11,6 @@ testthat::test_that("Testing that `nix_build()` builds derivation", { path_subshell <- tempdir() - rix_init( - project_path = path_subshell, - rprofile_action = "overwrite", - message_type = "simple" - ) - rix( r_ver = "latest", overwrite = TRUE, @@ -29,4 +23,8 @@ testthat::test_that("Testing that `nix_build()` builds derivation", { project_path = path_subshell ) ) + + on.exit({ + unlink(path_subshell, recursive = TRUE, force = TRUE) + }) }) diff --git a/tests/testthat/test-rix.R b/tests/testthat/test-rix.R index d56f98f4..b030bac3 100644 --- a/tests/testthat/test-rix.R +++ b/tests/testthat/test-rix.R @@ -56,28 +56,33 @@ testthat::test_that("rix(), ide is 'other' or 'code'", { path_default_nix <- normalizePath(path_default_nix) save_default_nix_test <- function(ide, path_default_nix) { - rix( - r_ver = "4.3.1", - r_pkgs = c("data.table", "janitor", "AER@1.2-8", "quarto"), - tex_pkgs = c("amsmath"), - git_pkgs = list( - list( - package_name = "housing", - repo_url = "https://github.com/rap4all/housing/", - branch_name = "fusen", - commit = "1c860959310b80e67c41f7bbdc3e84cef00df18e" + # We need to add this because this function gets called + # twice, so the generated .Rprofile is there already and + # calling the function again raises the warning. + suppressWarnings( + rix( + r_ver = "4.3.1", + r_pkgs = c("data.table", "janitor", "AER@1.2-8", "quarto"), + tex_pkgs = c("amsmath"), + git_pkgs = list( + list( + package_name = "housing", + repo_url = "https://github.com/rap4all/housing/", + branch_name = "fusen", + commit = "1c860959310b80e67c41f7bbdc3e84cef00df18e" + ), + list( + package_name = "fusen", + repo_url = "https://github.com/ThinkR-open/fusen", + branch_name = "main", + commit = "d617172447d2947efb20ad6a4463742b8a5d79dc" + ) ), - list( - package_name = "fusen", - repo_url = "https://github.com/ThinkR-open/fusen", - branch_name = "main", - commit = "d617172447d2947efb20ad6a4463742b8a5d79dc" - ) - ), - ide = ide, - project_path = path_default_nix, - overwrite = TRUE, - shell_hook = NULL + ide = ide, + project_path = path_default_nix, + overwrite = TRUE, + shell_hook = NULL + ) ) file.path(path_default_nix, "default.nix") @@ -114,13 +119,16 @@ testthat::test_that("Quarto gets added to sys packages", { path_default_nix <- normalizePath(tempdir()) save_default_nix_test <- function(pkgs, interface, path_default_nix) { - rix( - r_ver = "4.3.1", - r_pkgs = pkgs, - ide = interface, - project_path = path_default_nix, - overwrite = TRUE, - shell_hook = NULL + # Because of rix_init, see above + suppressWarnings( + rix( + r_ver = "4.3.1", + r_pkgs = pkgs, + ide = interface, + project_path = path_default_nix, + overwrite = TRUE, + shell_hook = NULL + ) ) file.path(path_default_nix, "default.nix") @@ -147,6 +155,10 @@ testthat::test_that("Quarto gets added to sys packages", { ), name = "yes_quarto_default.nix" ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) @@ -171,13 +183,17 @@ testthat::test_that("r_pkgs = NULL and ide = 'rstudio' work together", { testthat::announce_snapshot_file("rix/null_pkgs_rstudio.nix") testthat::expect_snapshot_file( - path = save_default_nix_test( - pkgs = NULL, - interface = "rstudio", - path_default_nix - ), - name = "null_pkgs_rstudio.nix" - ) + path = save_default_nix_test( + pkgs = NULL, + interface = "rstudio", + path_default_nix + ), + name = "null_pkgs_rstudio.nix" + ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) @@ -200,9 +216,13 @@ testthat::test_that("If on darwin and ide = rstudio, raise warning", { } testthat::expect_warning( - save_default_nix_test(path_default_nix), - regexp = "refer to the macOS" - ) + save_default_nix_test(path_default_nix), + regexp = "refer to the macOS" + ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) testthat::test_that("If R version is 4.4.0, raise warning", { @@ -225,6 +245,10 @@ testthat::test_that("If R version is 4.4.0, raise warning", { save_default_nix_test(path_default_nix), regexp = "version is not available" ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) testthat::test_that("If R version is <= 4.1.1, raise warning", { @@ -247,6 +271,11 @@ testthat::test_that("If R version is <= 4.1.1, raise warning", { save_default_nix_test(path_default_nix), regexp = "older version of R" ) + + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) testthat::test_that("If R version is == 3.5.3, raise warning", { @@ -269,6 +298,10 @@ testthat::test_that("If R version is == 3.5.3, raise warning", { save_default_nix_test(path_default_nix), regexp = "older version of R" ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) }) testthat::test_that("rix(), bleeding_edge", { diff --git a/tests/testthat/test-rix_init.R b/tests/testthat/test-rix_init.R index 6612219f..5ed939c9 100644 --- a/tests/testthat/test-rix_init.R +++ b/tests/testthat/test-rix_init.R @@ -20,4 +20,8 @@ testthat::test_that("Snapshot test of rix_init()", { path = save_rix_init_test(path_env_nix), name = "golden_Rprofile.txt", ) + + on.exit({ + unlink(path_env_nix, recursive = TRUE, force = TRUE) + }) }) diff --git a/tests/testthat/test-with_nix.R b/tests/testthat/test-with_nix.R index 647c2e04..71c6e3ad 100644 --- a/tests/testthat/test-with_nix.R +++ b/tests/testthat/test-with_nix.R @@ -14,12 +14,6 @@ testthat::test_that("Testing `with_nix()` if Nix is installed", { path_subshell <- tempdir() - rix_init( - project_path = path_subshell, - rprofile_action = "overwrite", - message_type = "simple" - ) - # Suppress the warning related to generating an expression # for an old version of R suppressWarnings( @@ -49,6 +43,10 @@ testthat::test_that("Testing `with_nix()` if Nix is installed", { testthat::expect_true( all(c(2, 6, 5, 8, 9) == out_subshell) ) + + on.exit({ + unlink(path_subshell, recursive = TRUE, force = TRUE) + }) }) testthat::test_that("Test `with_nix()` if Nix is installed on R 4.2.0", { @@ -64,12 +62,6 @@ testthat::test_that("Test `with_nix()` if Nix is installed on R 4.2.0", { path_subshell <- tempdir() - rix_init( - project_path = path_subshell, - rprofile_action = "overwrite", - message_type = "simple" - ) - rix( r_ver = "4.2.0", overwrite = TRUE, @@ -91,28 +83,28 @@ testthat::test_that("Test `with_nix()` if Nix is installed on R 4.2.0", { testthat::expect_false( inherits(out_subshell, "data.frame") ) + + + on.exit({ + unlink(path_subshell, recursive = TRUE, force = TRUE) + }) + }) testthat::test_that("Test `with_nix()` correct .libPaths()", { skip_on_covr() - + if (isFALSE(is_nix_r_session())) { # needed for the GitHub test runners with system's R set_nix_path() } - + skip_if_not(nix_shell_available()) path_subshell <- tempdir() - rix_init( - project_path = path_subshell, - rprofile_action = "overwrite", - message_type = "simple" - ) - rix( r_ver = "4.3.1", overwrite = TRUE, @@ -132,5 +124,9 @@ testthat::test_that("Test `with_nix()` correct .libPaths()", { testthat::expect_true( is.character(out_subshell) ) + + on.exit({ + unlink(path_subshell, recursive = TRUE, force = TRUE) + }) }) From 2f1cfb001aab52821c40b70c8c9d27c273517dbf Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Mon, 1 Jul 2024 17:34:53 +0200 Subject: [PATCH 12/21] handling cases where .Rprofile was already generated by rix_init() --- tests/testthat/_snaps/rix/one_git_default.nix | 2 +- tests/testthat/test-nix_build.R | 2 +- tests/testthat/test-rix.R | 52 ++++++++++++++++++- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/tests/testthat/_snaps/rix/one_git_default.nix b/tests/testthat/_snaps/rix/one_git_default.nix index b1c3a1b7..a051bf33 100644 --- a/tests/testthat/_snaps/rix/one_git_default.nix +++ b/tests/testthat/_snaps/rix/one_git_default.nix @@ -1,6 +1,6 @@ let - pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/976fa3369d722e76f37c77493d99829540d43845.tar.gz") {}; git_archive_pkgs = [ (pkgs.rPackages.buildRPackage { diff --git a/tests/testthat/test-nix_build.R b/tests/testthat/test-nix_build.R index 4c756f40..403c911a 100644 --- a/tests/testthat/test-nix_build.R +++ b/tests/testthat/test-nix_build.R @@ -12,7 +12,7 @@ testthat::test_that("Testing that `nix_build()` builds derivation", { path_subshell <- tempdir() rix( - r_ver = "latest", + r_ver = "4.3.1", overwrite = TRUE, project_path = path_subshell, shell_hook = NULL diff --git a/tests/testthat/test-rix.R b/tests/testthat/test-rix.R index b030bac3..108154e6 100644 --- a/tests/testthat/test-rix.R +++ b/tests/testthat/test-rix.R @@ -428,7 +428,7 @@ testthat::test_that("rix(), only one Github package", { save_default_nix_test <- function(path_default_nix) { - rix(r_ver = "latest", + rix(r_ver = "4.3.1", r_pkgs = NULL, system_pkgs = NULL, git_pkgs = list(package_name = "lookup", @@ -466,7 +466,7 @@ testthat::test_that("rix(), conclusion message", { save_default_nix_test <- function(path_default_nix) { - rix(r_ver = "latest", + rix(r_ver = "4.3.1", ide = "other", project_path = path_default_nix, message_type = "simple", @@ -485,3 +485,51 @@ testthat::test_that("rix(), conclusion message", { unlink(path_default_nix, recursive = TRUE, force = TRUE) }) }) + + +testthat::test_that("rix(), warning message if rix_init() already called", { + + testthat::skip_on_os + + path_default_nix <- paste0( + tempdir(), paste0(sample(letters, 5), collapse = "") + ) + dir.create(path_default_nix) + path_default_nix <- normalizePath(path_default_nix) + + rix_init( + project_path = path_default_nix, + rprofile_action = "overwrite", + message_type = "simple" + ) + + # Remove lines starting with # so rix() thinks the + # .Rprofile file was not generated by rix_init() + system( + paste0("sed -i '/^#/d' ", + file.path(path_default_nix, ".Rprofile")) + ) + + + save_default_nix_test <- function(path_default_nix) { + + rix(r_ver = "4.3.1", + ide = "other", + project_path = path_default_nix, + message_type = "simple", + overwrite = TRUE + ) + + file.path(path_default_nix, "default.nix") + } + + testthat::expect_warning( + save_default_nix_test(path_default_nix), + regexp = "You may" + ) + + on.exit({ + unlink(path_default_nix, recursive = TRUE, force = TRUE) + }) +}) + From c7e124c888ddf9dfb80497a0f32d0a63587b3854 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 20:25:47 +0200 Subject: [PATCH 13/21] use `message_type = "simple"` as default (consistency in rix) --- R/rix.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/rix.R b/R/rix.R index f4041c75..e3ced023 100644 --- a/R/rix.R +++ b/R/rix.R @@ -146,7 +146,7 @@ rix <- function(r_ver = "latest", project_path = ".", overwrite = FALSE, print = FALSE, - message_type = "verbose", + message_type = "simple", shell_hook = NULL) { message_type <- match.arg(message_type, From b9b1e3133c12727432e2da939ee7b65e4b7b4c93 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 20:36:18 +0200 Subject: [PATCH 14/21] please CRAN and R --- R/rix.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/rix.R b/R/rix.R index e3ced023..07a05cc2 100644 --- a/R/rix.R +++ b/R/rix.R @@ -153,7 +153,7 @@ rix <- function(r_ver = "latest", choices = c("quiet", "simple", "verbose") ) - if (!(message_type %in% c("simple", "quiet")) & r_ver %in% c("bleeding_edge", "frozen_edge")) { + if (!(message_type %in% c("simple", "quiet")) && r_ver %in% c("bleeding_edge", "frozen_edge")) { warning( "You chose 'bleeding_edge' or 'frozen_edge' as the value for `r_ver`. Please read the vignette @@ -162,13 +162,13 @@ before continuing." ) } - if(message_type != "quiet" & r_ver %in% available_r() & r_ver != "latest" & r_ver <= "4.1.1"){ + if(message_type != "quiet" && r_ver %in% available_r() && r_ver != "latest" && r_ver <= "4.1.1"){ warning( "You are generating an expression for an older version of R.\n To use this environment, you should directly use `nix-shell` and not try to build it first using `nix-build`." ) } - if(message_type != "quiet" & r_ver == "4.4.0"){ + if(message_type != "quiet" && r_ver == "4.4.0"){ warning( "You chose '4.4.0' as the R version, however this version is not available in nixpkgs. The generated expression will thus install R version 4.4.1." ) From 31399a9748b61280fcaf0c78d638a3a13cde3f84 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 20:59:36 +0200 Subject: [PATCH 15/21] update docs --- R/rix.R | 27 +++++++++++++++++++-------- man/rix.Rd | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/R/rix.R b/R/rix.R index 07a05cc2..53defe96 100644 --- a/R/rix.R +++ b/R/rix.R @@ -294,8 +294,22 @@ for more details." if (!file.exists(default.nix_path) || overwrite) { writeLines(default.nix, default.nix_path) - - if(!file.exists(.Rprofile_path)){ + + if (file.exists(.Rprofile_path)) { + if (all(!grepl("File generated by `rix::rix_init()", + readLines(.Rprofile_path)))) { + if (message_type != "quiet"){ + message("\n\n### Successfully generated `default.nix` ###\n\n") + } + warning("\n\n### .Rprofile file already exists. You may want to call rix_init(profile_action = 'append') manually to ensure correct functioning of your Nix environment. ###\n\n") + } else { + if (message_type != "quiet"){ + message("\n\n### Successfully generated `default.nix`. ", + "Keeping `.Rprofile` generated by `rix::rix_init()`###\n\n") + } + } + } + else if (!file.exists(.Rprofile_path)){ rix_init(project_path = project_path, rprofile_action = "create_missing", # 'verbose' is too chatty for rix() @@ -303,21 +317,18 @@ for more details." message_type = ifelse(message_type == "verbose", "simple", message_type)) - if(message_type != "quiet"){ + if (message_type != "quiet"){ message("\n\n### Successfully generated `default.nix` and `.Rprofile` ###\n\n") } - } else if(all(!grepl("File generated by `rix::rix_init()", - readLines(.Rprofile_path)))){ - warning("\n\n### .Rprofile file already exists. You may want to call rix_init(profile_action = 'append') manually to ensure correct functioning of your Nix environment. ###\n\n") } } else { - project_path <- if(project_path == ".") { + project_path <- if (project_path == ".") { "current folder" } else { project_path } - stop(paste0("default.nix exists in ", project_path, ". Set `overwrite == TRUE` to overwrite.")) + stop(paste0("`default.nix` exists in ", project_path, ". Set `overwrite == TRUE` to overwrite.")) } } diff --git a/man/rix.Rd b/man/rix.Rd index ed33b607..d6beb5d3 100644 --- a/man/rix.Rd +++ b/man/rix.Rd @@ -15,7 +15,7 @@ rix( project_path = ".", overwrite = FALSE, print = FALSE, - message_type = "verbose", + message_type = "simple", shell_hook = NULL ) } From 705efef90784120308669e7462ed33f83bc0bc34 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 21:02:29 +0200 Subject: [PATCH 16/21] use `file.path()` for file paths --- R/rix.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/rix.R b/R/rix.R index 53defe96..ab6745db 100644 --- a/R/rix.R +++ b/R/rix.R @@ -204,13 +204,13 @@ for more details." default.nix_path <- if (project_path == ".") { "default.nix" } else { - paste0(project_path, "/default.nix") + file.path(project_path, "default.nix") } .Rprofile_path <- if (project_path == ".") { ".Rprofile" } else { - paste0(project_path, "/.Rprofile") + file.path(project_path, ".Rprofile") } # Find url to use @@ -304,7 +304,7 @@ for more details." warning("\n\n### .Rprofile file already exists. You may want to call rix_init(profile_action = 'append') manually to ensure correct functioning of your Nix environment. ###\n\n") } else { if (message_type != "quiet"){ - message("\n\n### Successfully generated `default.nix`. ", + message("\n\n### Successfully generated `default.nix` in . ", "Keeping `.Rprofile` generated by `rix::rix_init()`###\n\n") } } From 26cac1d7790032f286a55da6d1f96b2ffb9b3d97 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 21:03:51 +0200 Subject: [PATCH 17/21] `profile_action` -> `rprofile_action` --- R/rix.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/rix.R b/R/rix.R index ab6745db..436a8858 100644 --- a/R/rix.R +++ b/R/rix.R @@ -301,7 +301,9 @@ for more details." if (message_type != "quiet"){ message("\n\n### Successfully generated `default.nix` ###\n\n") } - warning("\n\n### .Rprofile file already exists. You may want to call rix_init(profile_action = 'append') manually to ensure correct functioning of your Nix environment. ###\n\n") + warning("\n\n### .Rprofile file already exists. ", + "You may want to call rix_init(rprofile_action = 'append') manually ", + "to ensure correct functioning of your Nix environment. ###\n\n") } else { if (message_type != "quiet"){ message("\n\n### Successfully generated `default.nix` in . ", From 8121ddfb0b928b443e9b71fbf36bde5ed7174568 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 21:10:21 +0200 Subject: [PATCH 18/21] message if keeping valid `rix_init()` `.Rprofile` --- R/rix.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/rix.R b/R/rix.R index 436a8858..11227809 100644 --- a/R/rix.R +++ b/R/rix.R @@ -306,7 +306,11 @@ for more details." "to ensure correct functioning of your Nix environment. ###\n\n") } else { if (message_type != "quiet"){ - message("\n\n### Successfully generated `default.nix` in . ", + message( + sprintf( + "\n\n### Successfully generated `default.nix` in %s. ", + normalizePath(project_path) + ), "Keeping `.Rprofile` generated by `rix::rix_init()`###\n\n") } } From a4387a9c1deb45ca2f577a0bb8bc0c6995d2ad56 Mon Sep 17 00:00:00 2001 From: Philipp Baumann Date: Mon, 1 Jul 2024 21:15:40 +0200 Subject: [PATCH 19/21] please CRAN --- R/rix.R | 4 +-- default.nix | 74 +++++++++++++++-------------------------------------- 2 files changed, 22 insertions(+), 56 deletions(-) diff --git a/R/rix.R b/R/rix.R index 11227809..60c5fe6b 100644 --- a/R/rix.R +++ b/R/rix.R @@ -183,7 +183,7 @@ before continuing." rserver = "rstudioServerWrapper" ) - if (message_type != "quiet" & Sys.info()["sysname"] == "Darwin" & ide == "rstudio") { + if (message_type != "quiet" && Sys.info()["sysname"] == "Darwin" && ide == "rstudio") { warning( "Your detected operating system is macOS, and you chose 'rstudio' as the IDE. Please note that 'rstudio' is not @@ -257,7 +257,7 @@ for more details." # If there are wrapped packages (for example for RStudio), passes the "wrapped_pkgs" # to buildInputs - flag_wrapper <- if (ide %in% names(attrib) & flag_rpkgs != "") "wrapped_pkgs" else "" + flag_wrapper <- if (ide %in% names(attrib) && flag_rpkgs != "") "wrapped_pkgs" else "" # Correctly formats shellHook for Nix's mkShell shell_hook <- if (!is.null(shell_hook) && nzchar(shell_hook)) { diff --git a/default.nix b/default.nix index 480909b6..123c511d 100644 --- a/default.nix +++ b/default.nix @@ -1,66 +1,32 @@ -# This file was generated by the {rix} R package v0.7.1 on 2024-06-28 +# This file was generated by the {rix} R package v0.7.1 on 2024-07-01 # with following call: -# >rix(r_ver = "bleeding_edge", -# > r_pkgs = c("devtools", -# > "diffviewer", -# > "fledge", -# > "lintr", -# > "styler", -# > "codetools", -# > "jsonlite", -# > "httr", -# > "sys", -# > "testthat", -# > "knitr", -# > "rmarkdown", -# > "precommit"), -# > system_pkgs = c("R", -# > "glibcLocalesUtf8", -# > "pandoc", -# > "nix"), -# > tex_pkgs = "scheme-small", -# > ide = "other", +# >rix(r_ver = "b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8", +# > r_pkgs = NULL, +# > system_pkgs = NULL, +# > git_pkgs = NULL, +# > local_pkgs = NULL, +# > tex_pkgs = NULL, +# > ide = c("other", +# > "code", +# > "radian", +# > "rstudio", +# > "rserver"), # > project_path = ".", # > overwrite = TRUE, # > print = FALSE, +# > message_type = "simple", # > shell_hook = NULL) -# It uses the `rstats-on-nix` fork of `nixpkgs` which provides bleeding -# edge packages and R. -# Only use bleeding edge packages if absolutely needed! -# Read more on https://b-rodrigues.github.io/rix/articles/z-bleeding_edge.html +# It uses nixpkgs' revision b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8 for reproducibility purposes +# which will install R version latest. # Report any issues to https://github.com/b-rodrigues/rix let - pkgs = import (fetchTarball "https://github.com/rstats-on-nix/nixpkgs/archive/refs/heads/r-daily.tar.gz") {}; - - rpkgs = builtins.attrValues { - inherit (pkgs.rPackages) - devtools - diffviewer - fledge - lintr - styler - codetools - jsonlite - httr - sys - testthat - knitr - rmarkdown - precommit; - }; - - tex = (pkgs.texlive.combine { - inherit (pkgs.texlive) - scheme-small; - }); - + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8.tar.gz") {}; + system_packages = builtins.attrValues { inherit (pkgs) R - glibcLocalesUtf8 - pandoc - nix - glibcLocales; + glibcLocales + nix; }; in @@ -74,6 +40,6 @@ pkgs.mkShell { LC_PAPER = "en_US.UTF-8"; LC_MEASUREMENT = "en_US.UTF-8"; - buildInputs = [ rpkgs tex system_packages ]; + buildInputs = [ system_packages ]; } From 6bc2e2dceae4cdb723840d73c67df32d3befbfc1 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Tue, 2 Jul 2024 08:06:45 +0200 Subject: [PATCH 20/21] restore default.nix --- default.nix | 74 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/default.nix b/default.nix index 123c511d..480909b6 100644 --- a/default.nix +++ b/default.nix @@ -1,32 +1,66 @@ -# This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +# This file was generated by the {rix} R package v0.7.1 on 2024-06-28 # with following call: -# >rix(r_ver = "b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8", -# > r_pkgs = NULL, -# > system_pkgs = NULL, -# > git_pkgs = NULL, -# > local_pkgs = NULL, -# > tex_pkgs = NULL, -# > ide = c("other", -# > "code", -# > "radian", -# > "rstudio", -# > "rserver"), +# >rix(r_ver = "bleeding_edge", +# > r_pkgs = c("devtools", +# > "diffviewer", +# > "fledge", +# > "lintr", +# > "styler", +# > "codetools", +# > "jsonlite", +# > "httr", +# > "sys", +# > "testthat", +# > "knitr", +# > "rmarkdown", +# > "precommit"), +# > system_pkgs = c("R", +# > "glibcLocalesUtf8", +# > "pandoc", +# > "nix"), +# > tex_pkgs = "scheme-small", +# > ide = "other", # > project_path = ".", # > overwrite = TRUE, # > print = FALSE, -# > message_type = "simple", # > shell_hook = NULL) -# It uses nixpkgs' revision b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8 for reproducibility purposes -# which will install R version latest. +# It uses the `rstats-on-nix` fork of `nixpkgs` which provides bleeding +# edge packages and R. +# Only use bleeding edge packages if absolutely needed! +# Read more on https://b-rodrigues.github.io/rix/articles/z-bleeding_edge.html # Report any issues to https://github.com/b-rodrigues/rix let - pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8.tar.gz") {}; - + pkgs = import (fetchTarball "https://github.com/rstats-on-nix/nixpkgs/archive/refs/heads/r-daily.tar.gz") {}; + + rpkgs = builtins.attrValues { + inherit (pkgs.rPackages) + devtools + diffviewer + fledge + lintr + styler + codetools + jsonlite + httr + sys + testthat + knitr + rmarkdown + precommit; + }; + + tex = (pkgs.texlive.combine { + inherit (pkgs.texlive) + scheme-small; + }); + system_packages = builtins.attrValues { inherit (pkgs) R - glibcLocales - nix; + glibcLocalesUtf8 + pandoc + nix + glibcLocales; }; in @@ -40,6 +74,6 @@ pkgs.mkShell { LC_PAPER = "en_US.UTF-8"; LC_MEASUREMENT = "en_US.UTF-8"; - buildInputs = [ system_packages ]; + buildInputs = [ rpkgs tex system_packages ]; } From 1e5a412bbb07e3536fc675b0b514e3d34bd82cf5 Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Tue, 2 Jul 2024 08:22:29 +0200 Subject: [PATCH 21/21] - Changed argument to in rix() --- .github/workflows/test-fetchlocal.yml | 4 +-- R/fetchers.R | 16 ++++++------ R/rix.R | 18 ++++++------- R/rix_helpers.R | 26 +++++++++---------- inst/extdata/default.nix | 8 +++--- man/rix.Rd | 6 ++--- ...alling-r-packages-in-a-nix-environment.Rmd | 2 +- ...ling-packages-with-remote-dependencies.Rmd | 3 +-- 8 files changed, 41 insertions(+), 42 deletions(-) diff --git a/.github/workflows/test-fetchlocal.yml b/.github/workflows/test-fetchlocal.yml index 1a247892..b98ee275 100644 --- a/.github/workflows/test-fetchlocal.yml +++ b/.github/workflows/test-fetchlocal.yml @@ -35,14 +35,14 @@ jobs: - name: Build default.nix with 2 local packages run: | - nix-shell ./inst/extdata/default.nix --run "Rscript -e \"library(rix);rix('4.3.1', local_pkgs = c('chronicler_0.2.1.tar.gz', 'knitr_1.43.tar.gz'), overwrite = TRUE)\"" + nix-shell ./inst/extdata/default.nix --run "Rscript -e \"library(rix);rix('4.3.1', local_r_pkgs = c('chronicler_0.2.1.tar.gz', 'knitr_1.43.tar.gz'), overwrite = TRUE)\"" - name: Build default.nix run: nix-build - name: Build default.nix with 1 local package run: | - nix-shell ./inst/extdata/default.nix --run "Rscript -e \"library(rix);rix('4.3.1', local_pkgs = 'chronicler_0.2.1.tar.gz', overwrite = TRUE)\"" + nix-shell ./inst/extdata/default.nix --run "Rscript -e \"library(rix);rix('4.3.1', local_r_pkgs = 'chronicler_0.2.1.tar.gz', overwrite = TRUE)\"" - name: Build default.nix run: nix-build \ No newline at end of file diff --git a/R/fetchers.R b/R/fetchers.R index acb91a4f..f9c53779 100644 --- a/R/fetchers.R +++ b/R/fetchers.R @@ -193,25 +193,25 @@ fetchlocal <- function(local_pkg) { } #' fetchlocals Installs a local R package -#' @param local_pkgs Either a list of paths to local packages, or a path to a +#' @param local_r_pkgs Either a list of paths to local packages, or a path to a #' single package #' @return A character. The Nix definition to build the local R packages from #' local sources. #' @noRd -fetchlocals <- function(local_pkgs) { - paths_exist <- file.exists(local_pkgs) +fetchlocals <- function(local_r_pkgs) { + paths_exist <- file.exists(local_r_pkgs) if (!all(paths_exist)) { stop( paste0( - "local_pkgs: The following paths are incorrect:\n", - paste(local_pkgs[!paths_exist], collapse = "\n") + "local_r_pkgs: The following paths are incorrect:\n", + paste(local_r_pkgs[!paths_exist], collapse = "\n") ) ) - } else if (length(local_pkgs) == 1) { - fetchlocal(local_pkgs) + } else if (length(local_r_pkgs) == 1) { + fetchlocal(local_r_pkgs) } else { - paste(lapply(local_pkgs, fetchlocal), collapse = "\n") + paste(lapply(local_r_pkgs, fetchlocal), collapse = "\n") } } diff --git a/R/rix.R b/R/rix.R index 60c5fe6b..eb2ffc66 100644 --- a/R/rix.R +++ b/R/rix.R @@ -22,7 +22,7 @@ #' \url{https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=} #' @param git_pkgs List. A list of packages to install from Git. See details for #' more information. -#' @param local_pkgs List. A list of local packages to install. These packages +#' @param local_r_pkgs List. A list of local packages to install. These packages #' need to be in the `.tar.gz` or `.zip` formats and must be in the same #' folder as the generated "default.nix" file. #' @param tex_pkgs Vector of characters. A set of TeX packages to install. Use @@ -127,7 +127,7 @@ #' r_pkgs = c("dplyr", "ggplot2"), #' system_pkgs = NULL, #' git_pkgs = NULL, -#' local_pkgs = NULL, +#' local_r_pkgs = NULL, #' ide = "code", #' project_path = path_default_nix, #' overwrite = TRUE, @@ -140,7 +140,7 @@ rix <- function(r_ver = "latest", r_pkgs = NULL, system_pkgs = NULL, git_pkgs = NULL, - local_pkgs = NULL, + local_r_pkgs = NULL, tex_pkgs = NULL, ide = c("other", "code", "radian", "rstudio", "rserver"), project_path = ".", @@ -248,11 +248,11 @@ for more details." "" } - # If there are R packages local packages, passes the string "local_pkgs" to buildInputs - flag_local_pkgs <- if (is.null(local_pkgs)) { + # If there are R packages local packages, passes the string "local_r_pkgs" to buildInputs + flag_local_r_pkgs <- if (is.null(local_r_pkgs)) { "" } else { - "local_pkgs" + "local_r_pkgs" } # If there are wrapped packages (for example for RStudio), passes the "wrapped_pkgs" @@ -276,12 +276,12 @@ for more details." generate_rpkgs(cran_pkgs$rPackages, flag_rpkgs), generate_git_archived_pkgs(git_pkgs, cran_pkgs$archive_pkgs, flag_git_archive), generate_tex_pkgs(tex_pkgs), - generate_local_pkgs(local_pkgs, flag_local_pkgs), + generate_local_r_pkgs(local_r_pkgs, flag_local_r_pkgs), generate_system_pkgs(system_pkgs, r_pkgs), - generate_wrapped_pkgs(ide, attrib, flag_git_archive, flag_rpkgs, flag_local_pkgs), + generate_wrapped_pkgs(ide, attrib, flag_git_archive, flag_rpkgs, flag_local_r_pkgs), generate_shell( flag_git_archive, flag_rpkgs, flag_tex_pkgs, - flag_local_pkgs, flag_wrapper, shell_hook + flag_local_r_pkgs, flag_wrapper, shell_hook ), collapse = "\n" ) diff --git a/R/rix_helpers.R b/R/rix_helpers.R index a0b91479..c8f01018 100644 --- a/R/rix_helpers.R +++ b/R/rix_helpers.R @@ -137,21 +137,21 @@ generate_rpkgs <- function(rPackages, flag_rpkgs) { } } -#' generate_local_pkgs Internal function that generates the string containing the correct Nix expression for installing local packages -#' @param local_pkgs Character, list of local R packages to install. -#' @param flag_local_pkgs Character, are there any local R packages at all? +#' generate_local_r_pkgs Internal function that generates the string containing the correct Nix expression for installing local packages +#' @param local_r_pkgs Character, list of local R packages to install. +#' @param flag_local_r_pkgs Character, are there any local R packages at all? #' @noRd -generate_local_pkgs <- function(local_pkgs, flag_local_pkgs) { - if (flag_local_pkgs == "") { +generate_local_r_pkgs <- function(local_r_pkgs, flag_local_r_pkgs) { + if (flag_local_r_pkgs == "") { NULL } else { sprintf( " - local_pkgs = [ + local_r_pkgs = [ %s ]; ", - fetchlocals(local_pkgs) + fetchlocals(local_r_pkgs) ) } } @@ -272,13 +272,13 @@ generate_locale_variables <- function() { #' @param attrib Character, set the correct wrapper for the Nix expression. #' @param flag_git_archive Character, are there R packages from Github at all? #' @param flag_rpkgs Character, are there any R packages at all? -#' @param flag_local_pkgs Character, are there any local R packages at all? +#' @param flag_local_r_pkgs Character, are there any local R packages at all? #' @noRd generate_wrapped_pkgs <- function(ide, attrib, flag_git_archive, flag_rpkgs, - flag_local_pkgs) { + flag_local_r_pkgs) { if (flag_rpkgs == "") { return(NULL) } else if (ide %in% names(attrib)) { @@ -291,7 +291,7 @@ generate_wrapped_pkgs <- function(ide, attrib[ide], flag_git_archive, flag_rpkgs, - flag_local_pkgs + flag_local_r_pkgs ) } else { NULL @@ -303,14 +303,14 @@ generate_wrapped_pkgs <- function(ide, #' @param flag_git_archive Character, are there R packages from Github at all? #' @param flag_rpkgs Character, are there any R packages at all? #' @param flag_tex_pkgs Character, are there any LaTex packages at all? -#' @param flag_local_pkgs Character, are there any wrapped packages at all? +#' @param flag_local_r_pkgs Character, are there any wrapped packages at all? #' @param flag_wrapper Character, are there any wrapped packages at all? #' @param shell_hook Character, the mkShell's shellHook. #' @noRd generate_shell <- function(flag_git_archive, flag_rpkgs, flag_tex_pkgs, - flag_local_pkgs, + flag_local_r_pkgs, flag_wrapper, shell_hook) { sprintf( @@ -328,7 +328,7 @@ pkgs.mkShell { flag_git_archive, flag_rpkgs, flag_tex_pkgs, - flag_local_pkgs, + flag_local_r_pkgs, flag_wrapper, shell_hook ) diff --git a/inst/extdata/default.nix b/inst/extdata/default.nix index 629c9760..8ce63627 100644 --- a/inst/extdata/default.nix +++ b/inst/extdata/default.nix @@ -1,6 +1,6 @@ -# This file was generated by the {rix} R package v0.7.1 on 2024-07-01 +# This file was generated by the {rix} R package v0.7.1 on 2024-07-02 # with following call: -# >rix(r_ver = "12a9c0004bc987afb1ff511ebb97b67497a68e22", +# >rix(r_ver = "b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8", # > r_pkgs = NULL, # > system_pkgs = NULL, # > git_pkgs = list(package_name = "rix", @@ -11,11 +11,11 @@ # > project_path = "../inst/extdata", # > overwrite = TRUE, # > shell_hook = NULL) -# It uses nixpkgs' revision 12a9c0004bc987afb1ff511ebb97b67497a68e22 for reproducibility purposes +# It uses nixpkgs' revision b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8 for reproducibility purposes # which will install R version latest. # Report any issues to https://github.com/b-rodrigues/rix let - pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/12a9c0004bc987afb1ff511ebb97b67497a68e22.tar.gz") {}; + pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/b9014df496d5b68bf7c0145d0e9b0f529ce4f2a8.tar.gz") {}; git_archive_pkgs = [ (pkgs.rPackages.buildRPackage { diff --git a/man/rix.Rd b/man/rix.Rd index d6beb5d3..b0b8dbb0 100644 --- a/man/rix.Rd +++ b/man/rix.Rd @@ -9,7 +9,7 @@ rix( r_pkgs = NULL, system_pkgs = NULL, git_pkgs = NULL, - local_pkgs = NULL, + local_r_pkgs = NULL, tex_pkgs = NULL, ide = c("other", "code", "radian", "rstudio", "rserver"), project_path = ".", @@ -41,7 +41,7 @@ example. You can look for available software on the NixOS website \item{git_pkgs}{List. A list of packages to install from Git. See details for more information.} -\item{local_pkgs}{List. A list of local packages to install. These packages +\item{local_r_pkgs}{List. A list of local packages to install. These packages need to be in the \code{.tar.gz} or \code{.zip} formats and must be in the same folder as the generated "default.nix" file.} @@ -165,7 +165,7 @@ rix( r_pkgs = c("dplyr", "ggplot2"), system_pkgs = NULL, git_pkgs = NULL, - local_pkgs = NULL, + local_r_pkgs = NULL, ide = "code", project_path = path_default_nix, overwrite = TRUE, diff --git a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd index ec21e259..2f5549ed 100644 --- a/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd +++ b/vignettes/d1-installing-r-packages-in-a-nix-environment.Rmd @@ -325,7 +325,7 @@ and write something like this: ```{r, eval = F} rix(r_ver = '4.3.1', - local_pkgs = c('chronicler_0.2.1.tar.gz', 'knitr_1.43.tar.gz'), + local_r_pkgs = c('chronicler_0.2.1.tar.gz', 'knitr_1.43.tar.gz'), overwrite = TRUE) ``` diff --git a/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd b/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd index 0231a264..f0434440 100644 --- a/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd +++ b/vignettes/z-advanced-topic-handling-packages-with-remote-dependencies.Rmd @@ -44,8 +44,7 @@ Fortran. To create a reproducible development environment that makes [{lookup}](https://github.com/jimhester/lookup) available to you, you could use the following `rix::rix()` call: - -```{r, include = F } +```{r, eval = F} path_default_nix <- tempdir() rix(r_ver = "latest",