diff --git a/DESCRIPTION b/DESCRIPTION index ff7596fa..22117b14 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -10,6 +10,8 @@ Authors@R: c( Description: Provides helper functions to create reproducible development environments using the Nix package manager. License: GPL (>= 3) +URL: https://b-rodrigues.github.io/rix/ +BugReports: https://github.com/b-rodrigues/rix Depends: R (>= 2.10) Imports: diff --git a/R/detect_os.R b/R/detect_os.R index 530f478d..991ec7eb 100644 --- a/R/detect_os.R +++ b/R/detect_os.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/get_os.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_get_os.Rmd: do not edit by hand #' detect_os Detects the current OS #' @return A character. One of Linux or Darwin (Windows is also Linux) diff --git a/R/detect_versions.R b/R/detect_versions.R index fb9b9468..0a771279 100644 --- a/R/detect_versions.R +++ b/R/detect_versions.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/cran_archive.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_cran_archive.Rmd: do not edit by hand #' detect_versions Detects if CRAN packages need to be downloaded from the archive. #' @param r_pkgs A list of packages, to get from CRAN (either current packages or archived packages). diff --git a/R/find_rev.R b/R/find_rev.R index 15882dea..b539379f 100644 --- a/R/find_rev.R +++ b/R/find_rev.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/build_envs.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_build_envs.Rmd: do not edit by hand #' find_rev Find the right Nix revision #' @param r_version Character. R version to look for, for example, "4.2.0". If a nixpkgs revision is provided instead, this gets returned. diff --git a/R/included-datasets.R b/R/included-datasets.R index bcb68071..682c6d27 100644 --- a/R/included-datasets.R +++ b/R/included-datasets.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/data_doc.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_data_doc.Rmd: do not edit by hand #' r_nix_revs #' diff --git a/R/tar_nix_ga.R b/R/tar_nix_ga.R index 5972cbc2..b3b838d2 100644 --- a/R/tar_nix_ga.R +++ b/R/tar_nix_ga.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/cicd.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_cicd.Rmd: do not edit by hand #' tar_nix_ga Run a {targets} pipeline on Github Actions. #' @details This function puts a `.yaml` file inside the `.github/workflows/` diff --git a/R/zzz.R b/R/zzz.R index a5a9138b..404065aa 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/zzz.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_zzz.Rmd: do not edit by hand #' zzz Global imports #' @noRd diff --git a/README.Rmd b/README.Rmd index 6effe4b1..99a923d6 100644 --- a/README.Rmd +++ b/README.Rmd @@ -29,23 +29,29 @@ knitr::opts_chunk$set( ## Introduction -Nix is a package manager focusing on declarative and reproducible builds. This -makes Nix an incredibly useful piece of software for ensuring reproducibility of -projects, in research or otherwise, or for running web applications like Shiny -apps or `{plumber}` APIs in a controlled environment. - -Nix has quite a high entry cost though: this is because Nix is a complex piece -of software trying to solve a complex problem. - -`{rix}` is an R package that provides functions to help you write Nix -expressions: these expressions can then be used by the Nix package manager to +`{rix}` is an R package that leverages Nix, a powerful package manager focusing +on reproducible builds. With Nix, it is possible to create project-specific +environments that contain a project-specific version of R and R packages (as +well as other tools or languages, if needed). You can use `{rix}` and Nix to +replace `{renv}` and Docker with one single tool. Nix is an incredibly useful +piece of software for ensuring reproducibility of projects, in research or +otherwise, or for running web applications like Shiny apps or `{plumber}` APIs +in a controlled environment. + +Nix has quite a high entry cost though, because Nix is a complex piece of +software that comes with its own programming language (also called Nix) whose +purpose is to solve a complex problem: installing software in a reproducible +manner, on any operating system or hardware. + +`{rix}` provides functions to help you write Nix expressions (written in the Nix +language): these expressions can then be used by the Nix package manager to build completely reproducible development environments. These environments can be used for interactive data analysis or running pipelines in a CI/CD environment. Environments built with Nix contain R and all the required packages that you need for your project: there are currently more than 80.000 pieces of software available through the Nix package manager, including the entirety of -CRAN and Bioconductor packages. It is also possible to install older releases -of packages, or install packages from GitHub. +CRAN and Bioconductor packages. It is also possible to install older releases of +packages, or install packages from GitHub. The Nix package manager is extremely powerful: not only it handles all the dependencies of any package extremely well, it is also possible with it to @@ -53,11 +59,25 @@ reproduce environments containing old releases of software. It is thus possible to build environments that contain R version 4.0.0 (for example) to run an old project originally developed on that version of R. -With Nix, it is essentially possible to replace `{renv}` and Docker combined. If -you need other tools or languages like Python or Julia, this can also be done -easily. Nix is available for Linux, macOS and Windows (via WSL2). - -## Returning users +As stated above, with Nix, it is essentially possible to replace `{renv}` and +Docker combined. If you need other tools or languages like Python or Julia, this +can also be done easily. Nix is available for Linux, macOS and Windows (via +WSL2) and `{rix}` comes with the following features: + +- install any version of R and R packages for specific projects; +- have several versions of R and R packages installed at the same time on the + same system; +- define complete development environments as code and use them anywhere; +- run single function in a different environment (potentially with a different R + version and R packages) for an interactive R session and get back the output + of that function using `with_nix()`; + +`{rix}` does not require Nix to be installed on your system to generate +expressions. This means that you can generate expressions on a system on which +you cannot easily install software, and then use these expressions on the cloud +or on a CI/CD environment to build the project there. + +## Quick start for returning users *If you are not familiar with Nix or `{rix}` skip to the next section.* @@ -79,6 +99,7 @@ installing `{rix}`: ```{r, eval=FALSE} install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", "https://cloud.r-project.org")) + library("rix") ``` @@ -114,287 +135,13 @@ nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/m You can then create new development environment definitions, build them, and start using them. -## The Nix package manager - -Nix is a package manager that can be installed on your computer (regardless of -OS) and can be used to install software like with any other package manager. If -you're familiar with the Ubuntu Linux distribution, you likely have used -`apt-get` to install software. On macOS, you may have used `homebrew` for -similar purposes. Nix functions in a similar way, but has many advantages over -classic package managers. The main advantage of Nix, at least for our purposes, -is that its repository of software is huge. As of writing, it contains more than -80.000 packages, and the entirety of CRAN and Bioconductor is available through -Nix's repositories. This means that using Nix, it is possible to install not -only R, but also all the packages required for your project. The obvious -question is why use Nix instead of simply installing R and R packages as usual. -The answer is that Nix makes sure to install every dependency of any package, up -to required system libraries. For example, the `{xlsx}` package requires the -Java programming language to be installed on your computer to successfully -install. This can be difficult to achieve, and `{xlsx}` bullied many R -developers throughout the years (especially those using a Linux distribution, -`sudo R CMD javareconf` still plagues my nightmares). But with Nix, it suffices -to declare that we want the `{xlsx}` package for our project, and Nix figures -out automatically that Java is required and installs and configures it. It all -just happens without any required intervention from the user. The second -advantage of Nix is that it is possible to *pin* a certain *revision* of the Nix -packages' repository (called `nixpkgs`) for our project. Pinning a revision -ensures that every package that Nix installs will always be at exactly the same -versions, regardless of when in the future the packages get installed. - -## rix workflow - -The idea of `{rix}` is for you to declare the environment you need, using the -provided `rix()` function, which in turn writes the required expression in a -file for Nix to actually build that environment. You can then use this -environment to either work interactively, or run R scripts. It is possible to -have as many environments as projects. Each environment is isolated, but can -still interact with your system's files, unlike with Docker where a volume must -be mounted. - -The main function of `{rix}` is called `rix()`. `rix()` has several arguments: - -- the R version you need for your project; -- a list of R packages that your project needs; -- an optional list of additional software (for example a Python interpreter, or Quarto); -- an optional list with packages to install from Github; -- an optional list of LaTeX packages; -- whether you want to use RStudio as an IDE for your project (or VS Code, or another environment); -- a path to save a file called `default.nix`. - -For example: - -```{r, eval = FALSE} -rix(r_ver = "latest", - r_pkgs = c("dplyr", "chronicler"), - ide = "rstudio") -``` - -The call above writes a `default.nix` file in the current working directory. -This `default.nix` can in turn be used by Nix to build an environment containing -RStudio, the latest version of R, and the latest versions of the `{dplyr}` and -`{chronicler}` packages. It should be noted that as of January 2024, RStudio is -not available for macOS through Nix so the expression generated by the call -above will not build successfully on macOS and is not possible to use RStudio -installed by other means with a Nix environment. This is because RStudio changes -some default environment variables and a globally installed RStudio (the one you -install normally) would not recognize the R version installed in the Nix -environment. This is not the case for other IDEs such as VS code or Emacs. -For example: - -```{r, eval = FALSE} -rix(r_ver = "4.2.2", - r_pkgs = c("dplyr", "chronicler"), - ide = "code") -``` - -This call will generate a `default.nix` that installs R version 4.2.2, with the -`{dplyr}` and `{chronicler}` packages. Because the user wishes to use VS Code, -the `ide` argument was set to "code". This installs the required -`{languageserver}` package as well, but unlike `ide = "rstudio"` does not -install VS Code in that environment. Users should instead use the globally -installed VS Code by starting it from that environment. If you wish to also -install VS Code using Nix, you could change the above expression to this: - -```{r, eval = FALSE} -rix(r_ver = "4.2.2", - r_pkgs = c("dplyr", "chronicler"), - system_pkgs = "vscodium", - ide = "code") -``` - -or change "vscodium" to "vscode" if you prefer the MS branded version. - -It's also possible to install specific versions of packages: - -```{r, eval = FALSE} -rix(r_ver = "latest", - r_pkgs = c("dplyr@1.0.0"), - ide = "code") -``` - -but usually it is better to build an environment using the version of R that was -current at the time of the release of `{dplyr}` version 1.0.0, instead of using -the current version of R and install an old package. But depending on what you -need, you might need to run an old package on a current version of R, so we -offer this possibility as well. - -After running `rix()`, a `default.nix` is generated and can be used to build -an environment. - -### default.nix - -The Nix package manager can be used to build reproducible development -environments according to the specifications found in a file called -`default.nix`, which contains an *expression*. An *expression* is Nix jargon for -a function with multiple inputs and one output, this output being our -development environment. To make it easier for R programmers to use Nix, `{rix}` -can be used to write this file for you. `{rix}` does not require Nix to be -installed, so you could generate expressions and use them on other machines. To -actually build an environment using a `default.nix`, file, go to where you chose -to write it (ideally in a new, empty folder that will be the root folder of your -project) and use the Nix package manager to build the environment. Call the -following function in a terminal: - -``` -nix-build -``` - -`{rix}` also has a `nix_build()` helper function, so you can build environments -from an active R session if needed. - -Once Nix is done building the environment, you can start working on it -interactively by using the following command in a terminal emulator (not the R -console): - -``` -nix-shell -``` - -You will *drop* into a Nix shell. You can now call the IDE of your choice. For -RStudio, simply call: - -``` -rstudio -``` - -This will start RStudio. RStudio will use the version of R and library of -packages from that environment. - -It is also possible to specify software to install alongside R and R packages -with `rix()`, read the [Building reproducible development environments with rix -vignette](https://b-rodrigues.github.io/rix/articles/building-reproducible-development-environments-with-rix.html) -for more details. - -For more details on how to use a Nix environment using an IDE interactively, -read the [Interactive -use](https://b-rodrigues.github.io/rix/articles/interactive-use.html) vignette. - - -### Running single functions in a subshell - -It is also possible to run single functions in an isolated environment from an -active R session using `with_nix()` and get the output of that function loaded -into the current session. Refer to [this -vignette](https://b-rodrigues.github.io/rix/articles/running-r-or-shell-code-in-nix-from-r.html) -for more details on how to achieve this. Concretely this means that you could be -running R version 4.3.2 (installed via Nix, or not), and execute a function on R -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. - -### Running programs from an environment - -You could create a bash script that you put in the path to make the process of -launching RStudio from that environment more streamlined. For example, if your -project is called `housing`, you could create this script and execute it to -start your project: - -``` -!#/bin/bash -nix-shell /absolute/path/to/housing/default.nix --run rstudio -``` +## Getting started for new users -This will execute RStudio in the environment for the `housing` project. If you -use `{targets}` you could execute the pipeline in the environment by running: - -``` -cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'" -``` - -It's possible to execute the pipeline automatically using a so-called "shell -hook". See the -[Reproducible analytical pipelines with Nix](https://b-rodrigues.github.io/rix/articles/reproducible-analytical-pipelines-with-nix.html) -vignette for more details. - -## Installation - -You can install the development version of rix from [GitHub](https://github.com/) with: - -``` r -# install.packages("remotes") -remotes::install_github("b-rodrigues/rix") -``` - -Or you can install it from the [{rix} -r-universe](https://b-rodrigues.r-universe.dev/rix), which serves you from a -CRAN-like R package repository: - -```r -install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", - "https://cloud.r-project.org")) -``` - -As stated above, `{rix}` does not require Nix to be installed to generate -`default.nix` files. But if you are on a machine on which R is not already -installed, and you want to start using `{rix}` to generate `default.nix` files, -you could first start by installing Nix, and then use the following command to -drop into a temporary Nix shell that comes with R and `{rix}` pre-installed: - -``` -nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" -``` - -This should immediately start an R session inside your terminal. You can now run -something like this: - -``` -rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "other", - project_path = ".", - overwrite = TRUE) -``` - -to generate a `default.nix`, and then use that file to generate an environment -with R, `{dplyr}` and `{ggplot2}`. If you need to add packages for your -project, rerun the command above, but add the needed packages to `r_pkgs`. - -## Installing Nix - -### Windows pre-requisites - -If you are on Windows, you need the Windows Subsystem for Linux 2 (WSL2) to run -Nix. If you are on a recent version of Windows 10 or 11, you can simply run this -as an administrator in PowerShell: - -``` -wsl --install -``` - -You can find further installation notes at [this official MS -documentation](https://learn.microsoft.com/en-us/windows/wsl/install). - -We recommend to activate systemd in Ubuntu WSL2, mainly because this supports -other users than `root` running Nix. To set this up, please do as outlined -[this official Ubuntu blog entry](https://ubuntu.com/blog/ubuntu-wsl-enable-systemd): - -```sh -# in WSL2 Ubuntu shell -sudo -i -nano /etc/wsl.conf -# add this entry -[boot] -systemd=true -# then restart running instance from PowerShell -wsl --shutdown -# relaunch Ubuntu WSL2 -``` - -Afterwards, you can install Nix like business as usual. You can proceed with the -Determinate Systems installer. If you cannot or have decided not to activate -systemd, then you have to append `--init none` to the command. More details -about this you can find at [The Determinante Nix -Installer](https://github.com/DeterminateSystems/nix-installer). - -### Installing Nix using the Determinate Systems installer - -To make installation and de-installation of Nix simple, we recommend the -Determinate Systems installer which you can find -[here](https://zero-to-nix.com/start/install). This installer works for any -system and make [uninstalling Nix very easy as -well](https://zero-to-nix.com/start/uninstall). +To get started with `{rix}` and Nix, you should read the following vignette +`vignette("1-getting_started")`. The vignettes are numbered to get you to learn +how to use `{rix}` and Nix smoothly. There’s a lot of info, so take your time +reading the vignettes. Don’t hesitate to open an issue if something is not +clear. ### Docker @@ -407,14 +154,29 @@ GNU/Linux distribution that uses Nix as its system package manager. This package is developed using the `{fusen}` package. If you want to contribute, please edit the `.Rmd` files found in the `dev/` folder. Then, inflate the package using `fusen::inflate_all()`. If no errors are found -(warning and notes are ok), then commit and open a PR. To learn how to use +(warning and notes are OK), then commit and open a PR. To learn how to use `{fusen}` (don't worry, it's super easy), refer to this [vignette](https://thinkr-open.github.io/fusen/articles/How-to-use-fusen.html). In our development workflow, we use [semantic versioning](https://semver.org) via [{fledge}](https://fledge.cynkra.com). +## Thanks + +Thanks to the [Nix community](https://nixos.org/community/) for making Nix +possible, and thanks to the community of R users on Nix for their work +packaging R and CRAN/Bioconductor packages for Nix (in particular [Justin +Bedő](https://github.com/jbedo), [Rémi Nicole](https://github.com/minijackson), +[nviets](https://github.com/nviets), [Chris +Hammill](https://github.com/cfhammill), [László +Kupcsik](https://github.com/Kupac), [Simon +Lackerbauer](https://github.com/ciil), +[MrTarantoga](https://github.com/MrTarantoga) and every other person from the +[Matrix Nixpkgs R channel](https://matrix.to/#/#r:nixos.org)). + ## Recommended reading +- [NixOS’s website](https://nixos.org/) +- [Nixpkgs’s GitHub repository](https://github.com/NixOS/nixpkgs) - [Nix for R series from Bruno's blog](https://www.brodrigues.co/tags/nix/). Or, in case you like video tutorials, watch [this one on Reproducible R development environments with Nix](https://www.youtube.com/watch?v=c1LhgeTTxaI) - [nix.dev tutorials](https://nix.dev/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs#pinning-nixpkgs) - [INRIA's Nix tutorial](https://nix-tutorial.gitlabpages.inria.fr/nix-tutorial/installation.html) diff --git a/README.md b/README.md index f361e96e..6a77b5fc 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,14 @@ -- [Reproducible Environments with - Nix](#reproducible-environments-with-nix) - - [Introduction](#introduction) - - [Returning users](#returning-users) - - [The Nix package manager](#the-nix-package-manager) - - [rix workflow](#rix-workflow) - - [default.nix](#defaultnix) - - [Running single functions in a - subshell](#running-single-functions-in-a-subshell) - - [Running programs from an - environment](#running-programs-from-an-environment) - - [Installation](#installation) - - [Installing Nix](#installing-nix) - - [Windows pre-requisites](#windows-pre-requisites) - - [Installing Nix using the Determinate Systems - installer](#installing-nix-using-the-determinate-systems-installer) - - [Docker](#docker) - - [Contributing](#contributing) - - [Recommended reading](#recommended-reading) +- [Reproducible Environments with + Nix](#reproducible-environments-with-nix) + - [Introduction](#introduction) + - [Quick start for returning + users](#quick-start-for-returning-users) + - [Getting started for new users](#getting-started-for-new-users) + - [Docker](#docker) + - [Contributing](#contributing) + - [Thanks](#thanks) + - [Recommended reading](#recommended-reading) @@ -35,17 +26,23 @@ rix](https://b-rodrigues.r-universe.dev/badges/rix?scale=1&color=pink&style=roun ## Introduction -Nix is a package manager focusing on declarative and reproducible -builds. This makes Nix an incredibly useful piece of software for -ensuring reproducibility of projects, in research or otherwise, or for -running web applications like Shiny apps or `{plumber}` APIs in a -controlled environment. - -Nix has quite a high entry cost though: this is because Nix is a complex -piece of software trying to solve a complex problem. - -`{rix}` is an R package that provides functions to help you write Nix -expressions: these expressions can then be used by the Nix package +`{rix}` is an R package that leverages Nix, a powerful package manager +focusing on reproducible builds. With Nix, it is possible to create +project-specific environments that contain a project-specific version of +R and R packages (as well as other tools or languages, if needed). You +can use `{rix}` and Nix to replace `{renv}` and Docker with one single +tool. Nix is an incredibly useful piece of software for ensuring +reproducibility of projects, in research or otherwise, or for running +web applications like Shiny apps or `{plumber}` APIs in a controlled +environment. + +Nix has quite a high entry cost though, because Nix is a complex piece +of software that comes with its own programming language (also called +Nix) whose purpose is to solve a complex problem: installing software in +a reproducible manner, on any operating system or hardware. + +`{rix}` provides functions to help you write Nix expressions (written in +the Nix language): these expressions can then be used by the Nix package manager to build completely reproducible development environments. These environments can be used for interactive data analysis or running pipelines in a CI/CD environment. Environments built with Nix contain R @@ -62,12 +59,27 @@ thus possible to build environments that contain R version 4.0.0 (for example) to run an old project originally developed on that version of R. -With Nix, it is essentially possible to replace `{renv}` and Docker -combined. If you need other tools or languages like Python or Julia, -this can also be done easily. Nix is available for Linux, macOS and -Windows (via WSL2). +As stated above, with Nix, it is essentially possible to replace +`{renv}` and Docker combined. If you need other tools or languages like +Python or Julia, this can also be done easily. Nix is available for +Linux, macOS and Windows (via WSL2) and `{rix}` comes with the following +features: + +- install any version of R and R packages for specific projects; +- have several versions of R and R packages installed at the same time + on the same system; +- define complete development environments as code and use them + anywhere; +- run single function in a different environment (potentially with a + different R version and R packages) for an interactive R session and + get back the output of that function using `with_nix()`; -## Returning users +`{rix}` does not require Nix to be installed on your system to generate +expressions. This means that you can generate expressions on a system on +which you cannot easily install software, and then use these expressions +on the cloud or on a CI/CD environment to build the project there. + +## Quick start for returning users *If you are not familiar with Nix or `{rix}` skip to the next section.* @@ -89,6 +101,7 @@ by first installing `{rix}`: ``` r install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", "https://cloud.r-project.org")) + library("rix") ``` @@ -123,287 +136,13 @@ installed, you can run a temporary R session with R using this command You can then create new development environment definitions, build them, and start using them. -## The Nix package manager - -Nix is a package manager that can be installed on your computer -(regardless of OS) and can be used to install software like with any -other package manager. If you’re familiar with the Ubuntu Linux -distribution, you likely have used `apt-get` to install software. On -macOS, you may have used `homebrew` for similar purposes. Nix functions -in a similar way, but has many advantages over classic package managers. -The main advantage of Nix, at least for our purposes, is that its -repository of software is huge. As of writing, it contains more than -80.000 packages, and the entirety of CRAN and Bioconductor is available -through Nix’s repositories. This means that using Nix, it is possible to -install not only R, but also all the packages required for your project. -The obvious question is why use Nix instead of simply installing R and R -packages as usual. The answer is that Nix makes sure to install every -dependency of any package, up to required system libraries. For example, -the `{xlsx}` package requires the Java programming language to be -installed on your computer to successfully install. This can be -difficult to achieve, and `{xlsx}` bullied many R developers throughout -the years (especially those using a Linux distribution, -`sudo R CMD javareconf` still plagues my nightmares). But with Nix, it -suffices to declare that we want the `{xlsx}` package for our project, -and Nix figures out automatically that Java is required and installs and -configures it. It all just happens without any required intervention -from the user. The second advantage of Nix is that it is possible to -*pin* a certain *revision* of the Nix packages’ repository (called -`nixpkgs`) for our project. Pinning a revision ensures that every -package that Nix installs will always be at exactly the same versions, -regardless of when in the future the packages get installed. - -## rix workflow - -The idea of `{rix}` is for you to declare the environment you need, -using the provided `rix()` function, which in turn writes the required -expression in a file for Nix to actually build that environment. You can -then use this environment to either work interactively, or run R -scripts. It is possible to have as many environments as projects. Each -environment is isolated, but can still interact with your system’s -files, unlike with Docker where a volume must be mounted. - -The main function of `{rix}` is called `rix()`. `rix()` has several -arguments: - -- the R version you need for your project; -- a list of R packages that your project needs; -- an optional list of additional software (for example a Python - interpreter, or Quarto); -- an optional list with packages to install from Github; -- an optional list of LaTeX packages; -- whether you want to use RStudio as an IDE for your project (or VS - Code, or another environment); -- a path to save a file called `default.nix`. - -For example: - -``` r -rix(r_ver = "latest", - r_pkgs = c("dplyr", "chronicler"), - ide = "rstudio") -``` - -The call above writes a `default.nix` file in the current working -directory. This `default.nix` can in turn be used by Nix to build an -environment containing RStudio, the latest version of R, and the latest -versions of the `{dplyr}` and `{chronicler}` packages. It should be -noted that as of January 2024, RStudio is not available for macOS -through Nix so the expression generated by the call above will not build -successfully on macOS and is not possible to use RStudio installed by -other means with a Nix environment. This is because RStudio changes some -default environment variables and a globally installed RStudio (the one -you install normally) would not recognize the R version installed in the -Nix environment. This is not the case for other IDEs such as VS code or -Emacs. For example: - -``` r -rix(r_ver = "4.2.2", - r_pkgs = c("dplyr", "chronicler"), - ide = "code") -``` - -This call will generate a `default.nix` that installs R version 4.2.2, -with the `{dplyr}` and `{chronicler}` packages. Because the user wishes -to use VS Code, the `ide` argument was set to “code”. This installs the -required `{languageserver}` package as well, but unlike -`ide = "rstudio"` does not install VS Code in that environment. Users -should instead use the globally installed VS Code by starting it from -that environment. If you wish to also install VS Code using Nix, you -could change the above expression to this: - -``` r -rix(r_ver = "4.2.2", - r_pkgs = c("dplyr", "chronicler"), - system_pkgs = "vscodium", - ide = "code") -``` - -or change “vscodium” to “vscode” if you prefer the MS branded version. - -It’s also possible to install specific versions of packages: - -``` r -rix(r_ver = "latest", - r_pkgs = c("dplyr@1.0.0"), - ide = "code") -``` - -but usually it is better to build an environment using the version of R -that was current at the time of the release of `{dplyr}` version 1.0.0, -instead of using the current version of R and install an old package. -But depending on what you need, you might need to run an old package on -a current version of R, so we offer this possibility as well. - -After running `rix()`, a `default.nix` is generated and can be used to -build an environment. - -### default.nix - -The Nix package manager can be used to build reproducible development -environments according to the specifications found in a file called -`default.nix`, which contains an *expression*. An *expression* is Nix -jargon for a function with multiple inputs and one output, this output -being our development environment. To make it easier for R programmers -to use Nix, `{rix}` can be used to write this file for you. `{rix}` does -not require Nix to be installed, so you could generate expressions and -use them on other machines. To actually build an environment using a -`default.nix`, file, go to where you chose to write it (ideally in a -new, empty folder that will be the root folder of your project) and use -the Nix package manager to build the environment. Call the following -function in a terminal: - - nix-build - -`{rix}` also has a `nix_build()` helper function, so you can build -environments from an active R session if needed. - -Once Nix is done building the environment, you can start working on it -interactively by using the following command in a terminal emulator (not -the R console): - - nix-shell - -You will *drop* into a Nix shell. You can now call the IDE of your -choice. For RStudio, simply call: - - rstudio - -This will start RStudio. RStudio will use the version of R and library -of packages from that environment. - -It is also possible to specify software to install alongside R and R -packages with `rix()`, read the [Building reproducible development -environments with rix -vignette](https://b-rodrigues.github.io/rix/articles/building-reproducible-development-environments-with-rix.html) -for more details. - -For more details on how to use a Nix environment using an IDE -interactively, read the [Interactive -use](https://b-rodrigues.github.io/rix/articles/interactive-use.html) -vignette. - -### Running single functions in a subshell - -It is also possible to run single functions in an isolated environment -from an active R session using `with_nix()` and get the output of that -function loaded into the current session. Refer to [this -vignette](https://b-rodrigues.github.io/rix/articles/running-r-or-shell-code-in-nix-from-r.html) -for more details on how to achieve this. Concretely this means that you -could be running R version 4.3.2 (installed via Nix, or not), and -execute a function on R 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. +## Getting started for new users -### Running programs from an environment - -You could create a bash script that you put in the path to make the -process of launching RStudio from that environment more streamlined. For -example, if your project is called `housing`, you could create this -script and execute it to start your project: - - !#/bin/bash - nix-shell /absolute/path/to/housing/default.nix --run rstudio - -This will execute RStudio in the environment for the `housing` project. -If you use `{targets}` you could execute the pipeline in the environment -by running: - - cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'" - -It’s possible to execute the pipeline automatically using a so-called -“shell hook”. See the [Reproducible analytical pipelines with -Nix](https://b-rodrigues.github.io/rix/articles/reproducible-analytical-pipelines-with-nix.html) -vignette for more details. - -## Installation - -You can install the development version of rix from -[GitHub](https://github.com/) with: - -``` r -# install.packages("remotes") -remotes::install_github("b-rodrigues/rix") -``` - -Or you can install it from the [{rix} -r-universe](https://b-rodrigues.r-universe.dev/rix), which serves you -from a CRAN-like R package repository: - -``` r -install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", - "https://cloud.r-project.org")) -``` - -As stated above, `{rix}` does not require Nix to be installed to -generate `default.nix` files. But if you are on a machine on which R is -not already installed, and you want to start using `{rix}` to generate -`default.nix` files, you could first start by installing Nix, and then -use the following command to drop into a temporary Nix shell that comes -with R and `{rix}` pre-installed: - - nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" - -This should immediately start an R session inside your terminal. You can -now run something like this: - - rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "other", - project_path = ".", - overwrite = TRUE) - -to generate a `default.nix`, and then use that file to generate an -environment with R, `{dplyr}` and `{ggplot2}`. If you need to add -packages for your project, rerun the command above, but add the needed -packages to `r_pkgs`. - -## Installing Nix - -### Windows pre-requisites - -If you are on Windows, you need the Windows Subsystem for Linux 2 (WSL2) -to run Nix. If you are on a recent version of Windows 10 or 11, you can -simply run this as an administrator in PowerShell: - - wsl --install - -You can find further installation notes at [this official MS -documentation](https://learn.microsoft.com/en-us/windows/wsl/install). - -We recommend to activate systemd in Ubuntu WSL2, mainly because this -supports other users than `root` running Nix. To set this up, please do -as outlined [this official Ubuntu blog -entry](https://ubuntu.com/blog/ubuntu-wsl-enable-systemd): - -``` sh -# in WSL2 Ubuntu shell -sudo -i -nano /etc/wsl.conf -# add this entry -[boot] -systemd=true -# then restart running instance from PowerShell -wsl --shutdown -# relaunch Ubuntu WSL2 -``` - -Afterwards, you can install Nix like business as usual. You can proceed -with the Determinate Systems installer. If you cannot or have decided -not to activate systemd, then you have to append `--init none` to the -command. More details about this you can find at [The Determinante Nix -Installer](https://github.com/DeterminateSystems/nix-installer). - -### Installing Nix using the Determinate Systems installer - -To make installation and de-installation of Nix simple, we recommend the -Determinate Systems installer which you can find -[here](https://zero-to-nix.com/start/install). This installer works for -any system and make [uninstalling Nix very easy as -well](https://zero-to-nix.com/start/uninstall). +To get started with `{rix}` and Nix, you should read the following +vignette `vignette("1-getting_started")`. The vignettes are numbered to +get you to learn how to use `{rix}` and Nix smoothly. There’s a lot of +info, so take your time reading the vignettes. Don’t hesitate to open an +issue if something is not clear. ### Docker @@ -417,31 +156,47 @@ distribution that uses Nix as its system package manager. This package is developed using the `{fusen}` package. If you want to contribute, please edit the `.Rmd` files found in the `dev/` folder. Then, inflate the package using `fusen::inflate_all()`. If no errors are -found (warning and notes are ok), then commit and open a PR. To learn +found (warning and notes are OK), then commit and open a PR. To learn how to use `{fusen}` (don’t worry, it’s super easy), refer to this [vignette](https://thinkr-open.github.io/fusen/articles/How-to-use-fusen.html). In our development workflow, we use [semantic versioning](https://semver.org) via [{fledge}](https://fledge.cynkra.com). +## Thanks + +Thanks to the [Nix community](https://nixos.org/community/) for making +Nix possible, and thanks to the community of R users on Nix for their +work packaging R and CRAN/Bioconductor packages for Nix (in particular +[Justin Bedő](https://github.com/jbedo), [Rémi +Nicole](https://github.com/minijackson), +[nviets](https://github.com/nviets), [Chris +Hammill](https://github.com/cfhammill), [László +Kupcsik](https://github.com/Kupac), [Simon +Lackerbauer](https://github.com/ciil), +[MrTarantoga](https://github.com/MrTarantoga) and every other person +from the [Matrix Nixpkgs R channel](https://matrix.to/#/#r:nixos.org)). + ## Recommended reading -- [Nix for R series from Bruno’s - blog](https://www.brodrigues.co/tags/nix/). Or, in case you like video - tutorials, watch [this one on Reproducible R development environments - with Nix](https://www.youtube.com/watch?v=c1LhgeTTxaI) -- [nix.dev - tutorials](https://nix.dev/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs#pinning-nixpkgs) -- [INRIA’s Nix - tutorial](https://nix-tutorial.gitlabpages.inria.fr/nix-tutorial/installation.html) -- [Nix pills](https://nixos.org/guides/nix-pills/) -- [Nix for Data - Science](https://github.com/nix-community/nix-data-science) -- [NixOS explained](https://christitus.com/nixos-explained/): NixOS is - an entire Linux distribution that uses Nix as its package manager. -- [Blog post: Nix with R and - devtools](https://rgoswami.me/posts/nix-r-devtools/) -- [Blog post: Statistical Rethinking and - Nix](https://rgoswami.me/posts/rethinking-r-nix/) -- [Blog post: Searching and installing old versions of Nix - packages](https://lazamar.github.io/download-specific-package-version-with-nix/) +- [NixOS’s website](https://nixos.org/) +- [Nixpkgs’s GitHub repository](https://github.com/NixOS/nixpkgs) +- [Nix for R series from Bruno’s + blog](https://www.brodrigues.co/tags/nix/). Or, in case you like + video tutorials, watch [this one on Reproducible R development + environments with Nix](https://www.youtube.com/watch?v=c1LhgeTTxaI) +- [nix.dev + tutorials](https://nix.dev/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs#pinning-nixpkgs) +- [INRIA’s Nix + tutorial](https://nix-tutorial.gitlabpages.inria.fr/nix-tutorial/installation.html) +- [Nix pills](https://nixos.org/guides/nix-pills/) +- [Nix for Data + Science](https://github.com/nix-community/nix-data-science) +- [NixOS explained](https://christitus.com/nixos-explained/): NixOS is + an entire Linux distribution that uses Nix as its package manager. +- [Blog post: Nix with R and + devtools](https://rgoswami.me/posts/nix-r-devtools/) +- [Blog post: Statistical Rethinking and + Nix](https://rgoswami.me/posts/rethinking-r-nix/) +- [Blog post: Searching and installing old versions of Nix + packages](https://lazamar.github.io/download-specific-package-version-with-nix/) diff --git a/_pkgdown.yml b/_pkgdown.yml index d71acfb9..1bebe6eb 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,4 +1,4 @@ -url: ~ +url: https://b-rodrigues.github.io/rix/ template: bootstrap: 5 diff --git a/data/r_nix_revs.rda b/data/r_nix_revs.rda index 02e576d9..46106679 100644 Binary files a/data/r_nix_revs.rda and b/data/r_nix_revs.rda differ diff --git a/dev/0-dev_history.Rmd b/dev/0-dev_history.Rmd index d0fbe247..a3a0c58c 100755 --- a/dev/0-dev_history.Rmd +++ b/dev/0-dev_history.Rmd @@ -17,9 +17,11 @@ fusen::fill_description( pkg = here::here(), fields = list( Title = "Rix: Reproducible Environments with Nix", + URL = "https://b-rodrigues.github.io/rix/", + BugReports = "https://github.com/b-rodrigues/rix", Description = "Provides helper functions to create reproducible development environments using the Nix package manager.", - Version = "0.0.9", - `Authors@R` = c + Version = "0.0.1", + `Authors@R` = c( person("Bruno", "Rodrigues", email = "bruno@brodrigues.co", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3211-3689")), person("Philipp", "Baumann", email = "baumann-philipp@protonmail.com", role = "aut", comment = c(ORCID = "0000-0002-3194-8975")) ) @@ -70,14 +72,14 @@ usethis::use_git() ```{r development-inflate, eval=FALSE} # Run but keep eval=FALSE to avoid infinite loop # Execute in the console directly -fusen::inflate(flat_file = "dev/save_r_nix_revs.Rmd", - vignette_name = "Save the Nix Package Versions data", +fusen::inflate(flat_file = "dev/flat_save_r_nix_revs.Rmd", + vignette_name = "Developers Vignette: Save the Nix Package Versions data", overwrite = TRUE) ``` ```{r} local({ - knitr::knit("vignettes/save-the-nix-package-versions-data.Rmd", + knitr::knit("vignettes/developers-vignette-save-the-nix-package-versions-data.Rmd", output = tempfile()) usethis::use_data(r_nix_revs, overwrite = TRUE) @@ -86,32 +88,38 @@ local({ ``` ```{r} -fusen::inflate(flat_file = "dev/data_doc.Rmd", +fusen::inflate(flat_file = "dev/flat_data_doc.Rmd", vignette_name = NA, overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/build_envs.Rmd", +fusen::inflate(flat_file = "dev/flat_build_envs.Rmd", vignette_name = NA, overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/cicd.Rmd", +fusen::inflate(flat_file = "dev/flat_cicd.Rmd", vignette_name = NA, overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/zzz.Rmd", +fusen::inflate(flat_file = "dev/flat_zzz.Rmd", vignette_name = NA, overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/get_os.Rmd", +fusen::inflate(flat_file = "dev/flat_get_os.Rmd", + vignette_name = NA, + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/flat_cran_archive.Rmd", vignette_name = NA, overwrite = TRUE) ``` @@ -119,26 +127,69 @@ fusen::inflate(flat_file = "dev/get_os.Rmd", # Vignettes for users ```{r} -fusen::inflate(flat_file = "dev/building_envs_with_rix.Rmd", - vignette_name = "Building reproducible development environments with {rix}", +fusen::inflate(flat_file = "dev/1-getting_started.Rmd", + vignette_name = "1 - Getting started", + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/2a-linux_win.Rmd", + vignette_name = "2a - Setting up and using rix on Linux and Windows", + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/2b-macos.Rmd", + vignette_name = "2b - Setting up and using rix on macOS", + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/3-building_envs_with_rix.Rmd", + vignette_name = "3 - Using rix to build project specific environments", + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/4a-install_r_pkgs.Rmd", + vignette_name = "4a - Installing R packages in a Nix environment", + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/4b-install_sys_pkgs.Rmd", + vignette_name = "4b - Installing system tools and TexLive packages in a Nix environment", + overwrite = TRUE) +``` + +```{r} +fusen::inflate(flat_file = "dev/5-interactive_use.Rmd", + vignette_name = "5 - Interactive use", + overwrite = TRUE) +``` + + +```{r} +fusen::inflate(flat_file = "dev/literate_programming.Rmd", + vignette_name = "Advanced topic: Building an environment for literate programming", overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/non_interactive_use.Rmd", - vignette_name = "Non-interactive use", +fusen::inflate(flat_file = "dev/pkgs_with_remotes.Rmd", + vignette_name = "Advanced topic: Handling packages with remote dependencies", overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/interactive_use.Rmd", - vignette_name = "Interactive use", +fusen::inflate(flat_file = "dev/raps_with_nix.Rmd", + vignette_name = "Advanced topic: Reproducible Analytical Pipelines with Nix", overwrite = TRUE) ``` ```{r} -fusen::inflate(flat_file = "dev/cran_archive.Rmd", - vignette_name = "Installing old packages from the CRAN archives", +fusen::inflate(flat_file = "dev/subshells.Rmd", + vignette_name = "Advanced topic: Running R or Shell Code in Nix from R", overwrite = TRUE) ``` diff --git a/dev/1-getting_started.Rmd b/dev/1-getting_started.Rmd new file mode 100644 index 00000000..b8a1e11e --- /dev/null +++ b/dev/1-getting_started.Rmd @@ -0,0 +1,112 @@ +--- +title: "1 - Getting started" +output: html_document +editor_options: + chunk_output_type: console + markdown: + wrap: 80 +--- + +## The Nix package manager + +Nix is a package manager that can be installed on your computer (regardless of +OS) and can be used to install software like with any other package manager. If +you're familiar with the Ubuntu Linux distribution, you likely have used +`apt-get` to install software. On macOS, you may have used `homebrew` for +similar purposes. Nix functions in a similar way, but has many advantages over +classic package managers. The main advantage of Nix, at least for our purposes, +is that its repository of software is huge. As of writing, it contains more than +80.000 packages, and the entirety of CRAN and Bioconductor is available through +Nix's repositories. This means that using Nix, it is possible to install not +only R, but also all the packages required for your project. The obvious +question is why use Nix instead of simply installing R and R packages as usual. +The answer is that Nix makes sure to install every dependency of any package, up +to required system libraries. For example, the `{xlsx}` package requires the +Java programming language to be installed on your computer to successfully +install. This can be difficult to achieve, and `{xlsx}` bullied many R +developers throughout the years (especially those using a Linux distribution, +`sudo R CMD javareconf` still plagues my nightmares). But with Nix, it suffices +to declare that we want the `{xlsx}` package for our project, and Nix figures +out automatically that Java is required and installs and configures it. It all +just happens without any required intervention from the user. The second +advantage of Nix is that it is possible to *pin* a certain *revision* of the Nix +packages' repository (called `nixpkgs`) for our project. Pinning a revision +ensures that every package that Nix installs will always be at exactly the same +versions, regardless of when in the future the packages get installed. + +## rix workflow + +The idea of `{rix}` is for you to declare the environment you need using the +provided `rix()` function. `rix()` is the package’s main function and generates +a file called `default.nix` which is then used by the Nix package manager to +build that environment. Ideally, you would set up such an environment for each +of your projects. You can then use this environment to either work +interactively, or run R scripts. It is possible to have as many environments as +projects, and software that is common to environments will simply be re-used and +not get re-installed to save space. Environments are isolated for each other, +but can still interact with your system's files, unlike with Docker where a +volume must be mounted. Environments can also interact with the software +installed on your computer through the usual means, which can sometimes lead to +issues. We have provided functions and documentation to avoid this, so take your +time read through the vignettes and you should be fine. + +`rix()` has several arguments: + +- the R version you need for your project; +- a list of R packages that your project needs; +- an optional list of additional software (for example a Python interpreter, or Quarto); +- an optional list with packages to install from Github; +- an optional list of LaTeX packages; +- whether you want to use RStudio as an IDE for your project (or VS Code, or another environment); +- the path to save the `default.nix` file (by default the current working directory) + +For example: + +```{r, eval = FALSE} +rix(r_ver = "latest", + r_pkgs = c("dplyr", "chronicler"), + ide = "other") +``` + +The call above writes a `default.nix` file in the current working directory. +This `default.nix` can in turn be used by Nix to build an environment containing +the latest version of R, with the `{dplyr}` and `{chronicler}` packages. + +Take note of the `ide = "other"` argument: this argument, and the values it +can take, are further discussed in the vignette `vignette("5-interactive_use")` +but continue reading this vignette and then vignettes numbered by a "4". + +### Using default.nix files + +The Nix package manager can be used to build reproducible development +environments according to the specifications found in the generated +`default.nix` files, which contain a Nix *expression*. An *expression* is Nix +jargon for a function with multiple inputs and one output, this output being our +development environment. `{rix}` does not require Nix to be installed to +generate valid expressions (but does require an internet connection), so you +could generate expressions and use them on other machines. To actually build an +environment using a `default.nix` file, go to where you chose to write it +(ideally in a new, empty folder that will be the root folder of your project) +and use the Nix package manager to build the environment. Call the following +function in a terminal: + +``` +nix-build +``` + +Once Nix is done building the environment, you can start working on it +interactively by using the following command in a terminal emulator (not the R +console): + +``` +nix-shell +``` + +You will *drop* into a Nix shell which provides the installed software. + +Now that you know more about Nix and `{rix}`, it is time to get these tools +installed on your system. + +- If you’re running either Linux or Windows, read the Linux or Windows vignette: `vignette("2a-setting-up-and-using-rix-on-linux-and-windows")` +- If you’re running macOS, read the macOS vignette: `vignette("2b-setting-up-and-using-rix-on-macos")` + diff --git a/dev/2a-linux_win.Rmd b/dev/2a-linux_win.Rmd new file mode 100644 index 00000000..0c402263 --- /dev/null +++ b/dev/2a-linux_win.Rmd @@ -0,0 +1,144 @@ +--- +title: "2a - Setting up and using rix on Linux and Windows" +output: html_document +editor_options: + chunk_output_type: console + markdown: + wrap: 80 +--- + +*This vignette will discuss Linux and Windows-specific topics. If you're not +using either of these systems, you can ignore this vignette, and read the +`vignette("2b-setting-up-and-using-rix-on-macos")` +vignette instead.* + +## Introduction + +When it comes to Nix, there are really only two supported operating systems: +macOS and Linux distributions. Windows is "supported" because it is actually +running Linux thanks to WSL2. In practice this means that Linux distributions +and Windows can be considered one system, and macOS another, separate, system. +Because Windows is really running Linux under the hood thanks to WSL2, this +means that WSL2 needs to be running on your Windows system before you attempt to +install Nix. But it is important to know that you can run `{rix}` even if you +don't have Nix installed, which means you can generate Nix expressions, you +just can't build them. + +### Windows pre-requisites + +If you are on Windows, you need the Windows Subsystem for Linux 2 (WSL2) to run +Nix. If you are on a recent version of Windows 10 or 11, you can simply run this +as an administrator in PowerShell: + +``` +wsl --install +``` + +You can find further installation notes at [this official MS +documentation](https://learn.microsoft.com/en-us/windows/wsl/install). + +We recommend to activate systemd in Ubuntu WSL2, mainly because this supports +other users than `root` running Nix. To set this up, please do as outlined +[this official Ubuntu blog entry](https://ubuntu.com/blog/ubuntu-wsl-enable-systemd): + +```sh +# in WSL2 Ubuntu shell +sudo -i +nano /etc/wsl.conf +# add this entry +[boot] +systemd=true +# then restart running instance from PowerShell +wsl --shutdown +# relaunch Ubuntu WSL2 +``` + +Afterwards, you can install Nix like business as usual. You can proceed with the +Determinate Systems installer. + +## Installing Nix + +You can use `{rix}` to generate Nix expressions even if you don't have Nix +installed on your system, but obviously, you need to install Nix if you actually +want to build the defined development environment and use them. Installing (and +uninstalling) Nix is quite simple, thanks to the installer from [Determinate +Systems](https://determinate.systems/posts/determinate-nix-installer), a company +that provides services and tools built on Nix. Simply open a terminal and run +the following line (on Windows, if you cannot or have decided not to activate +systemd, then you have to append `--init none` to the command. You can find more +details about this on [The Determinate Nix +Installer page](https://github.com/DeterminateSystems/nix-installer)): + +```{sh, eval=FALSE} +curl --proto '=https' --tlsv1.2 -sSf \ + -L https://install.determinate.systems/nix | \ + sh -s -- install +``` + +Once you have Nix installed, you can build the expressions you generate with `{rix}`! + +On Linux, once Nix is installed, all the software that will be installed through +Nix will be saved to the `/nix` directory on the root partition. It is common +for Linux users to have a separate partition for `/`, which may be small. +Complete development environments built with Nix can take up much space, so if +the available space on your root partition is limited, we advise you to mount the +`/nix` folder on another partition with more space (for example, a secondary +hard drive). For this, edit `/etc/fstab` and add the following line at the end: + +``` +/home/path_to/nix /nix none bind 0 0 +``` + +This will map `/nix` to `/home/path_to/nix` which can be on a larger partition. +If you have enough space on your root partition, you can ignore the above +instructions. + +## What if you don't have R already installed? + +If you have successfully installed Nix, but don't have yet R installed on your +system, you could install R as you would usually do on your operating system, +and then install the `{rix}` package, and from there, generated project-specific +expressions and build them. But you could also install R using Nix. Running the +following line in a terminal will drop you in an interactive R session that you +can use to start generating expressions: + +``` +nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" +``` + +This should immediately start an R session inside your terminal. You can now run +something like this: + +``` +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "other", + project_path = ".", + overwrite = TRUE) +``` + +to generate a `default.nix`, and then use that file to generate an environment +with R, `{dplyr}` and `{ggplot2}`. If you need to add packages for your project, +rerun the command above, but add the needed packages to `r_pkgs`. This is +detailled in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")` and +`vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`. + +## Generating expressions + +Once you have R installed, either through the usual installer for your operating +system, or through Nix as explained previously, you can now start building +project-specific development environments. + +Start an R session, and install `{rix}` if that's not already done. Because +`{rix}` is not yet on CRAN, the easiest way is to install it from its +r-universe: + +```{r, eval=FALSE} +install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", + "https://cloud.r-project.org")) +``` + +You can then use the `{rix}` package to generate expressions. Consult the +next vignette `vignette("3-using-rix-to-build-project-specific-environments")` to learn more. diff --git a/dev/2b-macos.Rmd b/dev/2b-macos.Rmd new file mode 100644 index 00000000..1e9ddbb4 --- /dev/null +++ b/dev/2b-macos.Rmd @@ -0,0 +1,133 @@ +--- +title: "2b - Setting up and using rix on macOS" +output: html_document +editor_options: + chunk_output_type: console + markdown: + wrap: 80 +--- + +*This vignette will discuss macOS-specific topics. If you're not using macOS, you +can ignore this vignette, and read the +`vignette("2a-setting-up-and-using-rix-on-linux-and-windows")` +vignette instead.* + +## Introduction + +When it comes to Nix, there are really only two supported operating systems: macOS +and Linux distributions. Windows is "supported" because it is actually 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 +idiosyncracies. This vignette details these. + +## Installing Nix + +You can use `{rix}` to generate Nix expressions even if you don't have Nix installed +on your system, but obviously, you need to install Nix if you actually want to +build the defined development environment and use them. Installing (and uninstalling) +Nix is quite simple, thanks to the installer from +[Determinate +Systems](https://determinate.systems/posts/determinate-nix-installer), a company +that provides services and tools built on Nix. Simply open a terminal and run the following +line: + +```{sh, eval=FALSE} +curl --proto '=https' --tlsv1.2 -sSf \ + -L https://install.determinate.systems/nix | \ + sh -s -- install +``` + +Once you have Nix installed, you can build the expressions you generate with `{rix}`! + +## What if you don't have R already installed? + +If you have successfully installed Nix, but don't have yet R installed on your +system, you could install R as you would usually do on your operating system, +and then install the `{rix}` package, and from there, generated project-specific +expressions and build them. But you could also install R using Nix. Running the +following line in a terminal will drop you in an interactive R session that you +can use to start generating expressions: + +``` +nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" +``` + +This should immediately start an R session inside your terminal. You can now run +something like this: + +``` +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "other", + project_path = ".", + overwrite = TRUE) +``` + +to generate a `default.nix`, and then use that file to generate an environment +with R, `{dplyr}` and `{ggplot2}`. If you need to add packages for your project, +rerun the command above, but add the needed packages to `r_pkgs`. This is +detailled in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")` and +`vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`. + +## Generating expressions + +Once you have R installed, either through the usual installer for your operating +system, or through Nix as explained previously, you can now start building +project-specific development environments. + +On macOS, generating expressions works just like on Linux and Windows. Start an +R session, and install `{rix}` if that's not already done. Because `{rix}` is +not yet on CRAN, the easiest way is to install it from its r-universe: + +```{r, eval=FALSE} +install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", + "https://cloud.r-project.org")) +``` + +You can then use the `{rix}` package to generate expressions. Consult the +next vignette `vignette("3-using-rix-to-build-project-specific-environments")` to learn more. + +## More macOS specificities + +### Shared libraries issue + +When using environments built with Nix on macOS, you might get error messages +refering to "shared libraries", which indicate that your user library of R +packages is interfering with the project-specific Nix environment. In this case, +you might want to set up a project-specific `.Rprofile` using `rix::rix_init()`. +This function generates an `.Rprofile` file on the root of your project and +ensures that the Nix environment only loads R packages from its own +project-specific library. This should solve the issue. + +### RStudio and other development interfaces on macOS + +As of writing, RStudio cannot be installed through `nixpkgs` for macOS, and if +you wish to use RStudio with a Nix environment, you have to install it through +`nixpkgs`. This means that it is impossible to use RStudio and a Nix environment +on macOS. When you try to generate an expression with `ide = +"rstudio"` on macOS, this will raise a warning. Here are the options you have: + +- ignore the warning, because the environment will be built on a Linux + distribution (even though you generated the expression on macOS) and used on a + Linux distribution; +- change the `ide =` argument to either `"other"` or `"code"`. Use `"code"` if + you want to use VS Code and `"other"` for any other editor, like Vim or Emacs. + These other editors don't need to be installed through `nixpkgs` to use Nix environments, + unlike RStudio; +- if you're working on a pipeline with the `{targets}` package, you could run it + on Github Actions. This means you could work on the code on RStudio outside + of the Nix environment, as the code will only be executed on Github Actions runners. See this + vignette `vignette("advanced-topic-reproducible-analytical-pipelines-with-nix")` for further details; +- work on your project as usual, using your usual installation of R and RStudio, + but generate a `default.nix` at the end with `ide = "other"` with the right + version of R for reproducibility purposes; +- use subshells to execute only the code you need to run in a specific + environment. See this vignette `vignette("advanced-topic-running-r-or-shell-code-in-nix-from-r")`; +- help us package RStudio for macOS on `nixpgs`. See + [https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/rstudio/default.nix](the + expression for RStudio). + +We recommend you continue with the next vignette before tackling the more advanced +topics listed above: `vignette("3-using-rix-to-build-project-specific-environments")`. diff --git a/dev/3-building_envs_with_rix.Rmd b/dev/3-building_envs_with_rix.Rmd new file mode 100644 index 00000000..67c58148 --- /dev/null +++ b/dev/3-building_envs_with_rix.Rmd @@ -0,0 +1,153 @@ +--- +title: "3 - Using rix to build project specific environments" +output: html_document +editor_options: + chunk_output_type: console +--- + +## Project-specific Nix environments + +Now that you have the required software installed, it’s to time learn more about +declaring and using reproducible inveronments. + +The ideal workflow when using `{rix}` is to create a new, separate environment +at the start of a project. Let's say that you wish to analyse some data set, and +need `{dplyr}` and `{ggplot2}`. Let's also suppose that you use VS Code as your +IDE (there will be more discussion on editors in the vignette +`vignette("5-interactive_use")` but for now, let’s assume that you use VS Code). +With the `rix::rix()` function, you can easily generate the right `default.nix` +file. You need to provide the following inputs to `rix()`: + +- `r_ver`: the version of R required. Use "latest" for the latest version; +- `r_pkgs`: the required R packages. For example "dplyr" (more on this in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")`); +- `system_pkgs`: the required system packages, if needed. For example "quarto", or a Python interpreter (more on this in the vignette `vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`); +- `git_pkgs`: list of git packages to add (more on this in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")`); +- `ide`: the integrated development editor to use (more on this in the vignette `vignette("5-interactive_use")`) +- `path`: the path where to save the `default.nix` file. +- `overwrite`: whether to overwrite the `default.nix` file or not. +- `print`: whether to print the `default.nix` file to the console or not. + +Run the following command to generate the right `default.nix` file: + +```{r} +path_default_nix <- tempdir() + +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "code", + project_path = path_default_nix, + overwrite = TRUE, + print = TRUE) +``` + +To start using this environment, open a terminal in the folder containing +`default.nix` and use the following Nix command: + +``` +nix-build +``` + +`nix-build` is a Nix command that builds an environment according to the +specifications found in a `default.nix` file. Once the environment is done +building, you should find a new file called `result` next to the `default.nix` +file. This file is a symlink to the software installed by Nix. `{rix}` also +provides a `nix_build()` function to build Nix environments from within an +interactive R session, but it is not always guaranteed to succeed, due to +differences in platforms. This is explained in more detail in the following +vignette `vignette("advanced-topic-running-r-or-shell-code-in-nix-from-r")`. In case of doubt, run `nix-build` from your +usual terminal application. + +To now use the environment, type in the same terminal as before: + +``` +nix-shell +``` + +This will activate the environment. If you have VS Code installed you can +start it from this environment and VS Code will use this specific R version +library of packages. We will explore this in greater detail in the vignette +`vignette("5-interactive_use")`. + +## Running old projects with {rix} + +The example below shows how to create a `default.nix` with instructions to build +an environment with R version 4.2.1, the `{dplyr}` and `{janitor}` packages and +no specific IDE: + +```{r} +path_default_nix <- tempdir() + +rix(r_ver = "4.2.1", + r_pkgs = c("dplyr", "janitor"), + system_pkgs = c("quarto"), + git_pkgs = NULL, + ide = "other", + project_path = path_default_nix, + overwrite = TRUE) + +``` + +The file looks like this: + +```{r, echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +The first line is quite important, as it shows which *revision* of `nixpkgs` is +being used for this environment. The *revision* is the commit hash of that +particular release of `nixpkgs`, here: `79b3d4bcae8`. This revision of `nixpkgs` +is the one that shipped version 4.2.1 of R, so the `{dplyr}` and `{janitor}` +packages that will get installed will be the versions available in that revision +as well. This means that R versions and package versions are always coupled when +using Nix. However, if you need a specific version of R, but also a specific +version of a package that is not available in that particular Nix revision, one +solution is to install that package from Github or fro the CRAN archives. Read +the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")` to know +more about this. To know which versions of R are available, read the documention +of `available_r()`. + +## Running programs from an environment + +You could create a bash script that you put in the path to make the process of +launching your editor from that environment more streamlined. For example, if your +project is called `housing`, you could create this script and execute it to +start your project: + +``` +!#/bin/bash +nix-shell /absolute/path/to/housing/default.nix --run code +``` + +This will execute VS Code in the environment for the `housing` project. If you +use `{targets}` you could execute the pipeline in the environment by running: + +``` +cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'" +``` + +## Running single functions in a subshell + +It is also possible to run single functions in an isolated environment from an +active R session using `with_nix()` and get the output of that function loaded +into the current session. Refer to this vignette +`vignette("advanced-topic-running-r-or-shell-code-in-nix-from-r")` for +more details on how to achieve this. Concretely this means that you could be +running R version 4.3.2 (installed via Nix, or not), and execute a function on R +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 +from the rest of the system. Suppose that you have the program `sl` installed on +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. diff --git a/dev/4a-install_r_pkgs.Rmd b/dev/4a-install_r_pkgs.Rmd new file mode 100644 index 00000000..683b8125 --- /dev/null +++ b/dev/4a-install_r_pkgs.Rmd @@ -0,0 +1,110 @@ +--- +title: "4a - Installing R packages in a Nix environment" +output: html_document +editor_options: + chunk_output_type: console + markdown: + wrap: 80 +--- + +## Introduction + +You now know how to declare and build reproducible development environments using `{rix}` +and Nix. This vignette will explain how to install specific versions of CRAN packages +and how to install packages from GitHub. + +## Installing old packages archived on CRAN + +It is possible to install an arbitrary version of a package that has been +archived on CRAN: + +```{r} +path_default_nix <- tempdir() + +rix(r_ver = "4.2.1", + 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) +``` + +```{r, echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +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 +packages that have been archived, but otherwise, this feature should ideally be +used sparingly. If you want to reconstruct an environment as it was around 2019, +use the version of R that was current at that time. This will ensure that every +package that gets installed is at a version compatible with that version of R, +which might not be the case if you need to install a very old version of one +particular package. + +## Installing packages from Github + +It is also possible to install packages from Github: + +```{r} +rix(r_ver = "4.2.1", + 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) + +``` + +```{r, echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +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 +is also installed, from the main branch at commit `d617172447d`. + +## A complete example + +This example shows how to install packages from CRAN, from the CRAN archives and +from GitHub: + +```{r} +rix(r_ver = "4.2.1", + 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) + +``` + +```{r, echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +The next vignette, +`vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`, +explains how you can install tools such as text editors, git, Quarto, TexLive +packages, and any other tool available through `nixpkgs` for your development +environments. diff --git a/dev/4b-install_sys_pkgs.Rmd b/dev/4b-install_sys_pkgs.Rmd new file mode 100644 index 00000000..3dca4b0c --- /dev/null +++ b/dev/4b-install_sys_pkgs.Rmd @@ -0,0 +1,94 @@ +--- +title: "4b - Installing system tools and TexLive packages in a Nix environment" +output: html_document +editor_options: + chunk_output_type: console + markdown: + wrap: 80 +--- + +## Introduction + +More than 80'000 pieces of software are available through the Nix package +managers. Nix’s repository of packages is called `nixpkgs` and it includes the +entirety of CRAN and Bioconductor. `nixpkgs` is actually "just" a Github +repository containing thousands upon thousands of Nix expressions. When +installing a package, these expressions get evaluated, and the package in +question gets installed. What installed means can vary: sometimes the package +gets built from source, sometimes a pre-compiled binary package for your +operating system gets downloaded and made available. + +For example, +[here](https://github.com/NixOS/nixpkgs/blob/dce218f4f35440622d2056f93ddc335351763bb4/pkgs/development/libraries/quarto/default.nix) +is the Nix expression that downloads and installs [Quarto](https://quarto.org/). +This is an example of an expression that downloads the pre-compiled Quarto +binary from Quarto’s own Github repository, and then installs it. The +installation process in this case is essentially making sure that Quarto is able +to find its dependencies, which also get installed from Nix, and some R and +Python packages to make Quarto work well with both languages also get installed. + +It is possible to use `rix()` to add tools to an environment and this vignette +explains how. + +## Adding tools to an environment + +The call below generates a `default.nix` that defines an environment with the 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} +path_default_nix <- tempdir() + +rix(r_ver = "latest", + r_pkgs = c("quarto"), + system_pkgs = c("quarto", "git"), + git_pkgs = NULL, + ide = "other", + project_path = path_default_nix, + overwrite = TRUE) +``` + +```{r, echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +You can look for all the available software +[here](https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=). +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 requires +a TexLive distribution to be installed. You can use `rix()` to install 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} +path_default_nix <- tempdir() + +rix(r_ver = "latest", + r_pkgs = c("quarto"), + system_pkgs = "quarto", + tex_pkgs = c("amsmath"), + ide = "other", + project_path = path_default_nix, + overwrite = TRUE, + print = TRUE) + +``` + +This will automically add the *small* TexLive distribution available through `nixpkgs` +with the `amsmath` LaTex package. To know more about setting up environments for +literate programming, refer to the vignette +`vignette("advanced-topic-building-an-environment-for-literate-programming")`. + +## Installing IDEs + +Environments built with Nix are not completely cut off from the rest of your +system, and as such, you should be able to use your usual IDE to interact with +Nix environments. The only exception is RStudio. Everything will be explained in +greater detail in the vignette `vignette("5-interactive_use")`. diff --git a/dev/5-interactive_use.Rmd b/dev/5-interactive_use.Rmd new file mode 100644 index 00000000..832bac71 --- /dev/null +++ b/dev/5-interactive_use.Rmd @@ -0,0 +1,163 @@ +--- +title: "5 - Interactive use" +output: html_document +editor_options: + chunk_output_type: console + markdown: + wrap: 80 +--- + +## Introduction + +This vignette describes interactive use of environments built with `{rix}` using +a GUI editor like RStudio. We will discuss three scenarios: one in which you +already have R and RStudio installed on your operating system using the usual +installation method for your operating system, another in which you used Nix +to install R and RStudio, and finally the last scenario assumes you use another +IDE than RStudio, for example VS Code, Emacs, Vim... + +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("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 +start using `{rix}` to define reproducible environments for your new projects +starting today. These environments will get built using the Nix package manager +and will not only include the required R packages for your project but also a +specific version of R, and any required system-level dependency as well. If you +are used to using RStudio, then you also need to install RStudio using Nix in +these project-specific environments. This is because RStudio re-defines many +environment variables and as such, a version of RStudio installed using the +usual installer for your operating system will not be able "to see" an R +interpreter installed with Nix. As stated in the macOS-specific vignette +`vignette("2b-setting-up-and-using-rix-on-macos")`, RStudio is not available on +macOS through `nixpkgs`. The following instructions are thus only applicable to +Linux and Windows. If you’re on macOS, read the macOS-specific vignette if +that’s not done already, and then come back here and skip to the "scenario 3" of +this vignette. + +To run a project-specific version of RStudio and R, you will first need to +create a `default.nix` file and build the environment defined therein using Nix. +Once this is done, you then need to activate the environment before running this +project-specific version of RStudio. Suppose for example that you generated a +`default.nix` file for a project called "kmeans", and suppose that this project +is in the following path: `~/Documents/kmeans` (on Windows it would be something +like `C:\Users\Billy\Documents\kmeans`). For example, here is how you could use +`{rix}` to generate the `default.nix` for this environment: + +```{r, 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, eval = FALSE} +library(rix) + +path_to_project <- ~/Documents/kmeans + +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "rstudio", + project_path = path_to_project, + overwrite = TRUE, + print = TRUE) +``` + +Navigate to that folder using your terminal, and then run `nix-shell`. You will +then be *dropped into* a Nix shell. From there 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}`. You can then work on +it as usual. + +You can also define a shortcut to a project that will take care of activating +the environment and launching RStudio. This way, you don't need to start a +terminal in that folder and drop into the Nix environment each time you want to +work on this project. For example, you could define a bash alias like this: + + alias kmeans='nix-shell ~/Documents/kmeans/default.nix --run rstudio + +which would then execute RStudio in the right project by simply typing `kmeans` +in a terminal. It's also possible to create an executable script that you can +save in your PATH: + + #!/usr/bin/env nix-shell + #!nix-shell /home/Billy/Document/kmeans/default.nix -i bash + rstudio + +Name this script something like `kmeans_project`, make it executable (using +`chmod +x kmeans_project`), and now you can run RStudio within this environment +from anywhere. + +## Scenario 2: you don't have any regular R and RStudio installation yet + +If you don't have R installed you cannot use the `{rix}` package to generate new +expressions. In this case you might consider installing Nix first, and then run +the following command inside your terminal to get dropped into a temporary Nix +shell, which you can then use to generate new `default.nix` files: + + nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" + +Running the command above will download R and `{rix}` and then start an R +session inside your terminal. You can now run something like this: + + rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "rstudio", + # change to a project's path or leave it if you're in the right folder already + project_path = ".", + overwrite = TRUE) + +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 +could install `{rix}` in that environment to generate new `default.nix` files. + +## Scenario 3: you use some IDE other than RStudio + +VS Code and Emacs have been tested and unlike RStudio, you can use a version of +VS Code or Emacs installed through the usual means on your system with +development environments built with Nix. But there's nothing stopping you from +installing a project-specific version of VS Code or Emacs as well if you wish. +Configuration and settings should be accessible across every version from every +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: + +``` +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "code", + project_path = ".", + overwrite = TRUE) +``` + +Notice the `ide = "code"` argument. This will not install VS Code from Nix, but +will install the `{languageserver}` package that is needed for using R with VS +Code. If you want to also install a project-specific version of VS Code, then +use `system_pkgs = "vscode"` or `system_pkgs = "vscodium"` if you prefer VS +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. + +## 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/dev/building_envs_with_rix.Rmd b/dev/building_envs_with_rix.Rmd deleted file mode 100644 index 920a2bf3..00000000 --- a/dev/building_envs_with_rix.Rmd +++ /dev/null @@ -1,268 +0,0 @@ ---- -title: "Building reproducible development environments with rix" -output: html_document -editor_options: - chunk_output_type: console ---- - -## Introduction and installation - -The goal of `{rix}` is to provide an easy way to generate `default.nix` files. -These files are used by the Nix package manager to build an environment -according to the instructions defined in it. Users can specify which version of -R, R packages, other needed software, IDE etc should be available within that -environment. Writing such files can be daunting for newcomers, and so `{rix}` -provides a function called `rix()`, which takes care of the bulk of the work - -`{rix}` does not require Nix to be installed to generate `default.nix` files, so -you could generate the file on one machine, and then build and use the -environment on another machine that has Nix installed on it (or on a CI/CD -service like Github Actions for example). If you wish to fully take advantage of -Nix, I suggest you use [Determinate System's -installer](https://zero-to-nix.com/start/install). Nix can be installed on -Linux, macOS and Windows (but on Windows WSL2 must be enabled). - -On Linux, once Nix is instaled, all the software that will be installed will be -saved to the `/nix` directory on the root partition. Complete development -environments built with Nix can take up much space, so if the available space on -your root parttion is limited, I advise you to mount the `/nix` folder on -another partition with more space (for example, a secondary hard drive). For -this, edit `/etc/fstab` and add the following line at the end: - -``` -/home/path_to/nix /nix none bind 0 0 -``` - -This will map `/nix` to `/home/path_to/nix` which can be on a larger partition. -If you have enough space on your root partition, you can ignore the above -instructions. - -## Nix environments - -An environment built by Nix is not totally isolated from the rest of the system. -Suppose that you the program `sl` installed on 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. This can -be useful when working interactively with a Nix environment, because you can use -your usual IDE to work with it. The only exception is RStudio: RStudio looks for -R in predefined paths and cannot "see" the R provided by a Nix environment, it -will instead use the version installed on your machine. This means that if you -use RStudio to work interactively with R, you will need to install RStudio -inside that environment. `rix::rix()` can generate a `default.nix` file that -does that. - -## Day-to-day use of {rix} - -The ideal workflow when using `{rix}` is to create a new, separate environment -at the start of a project. Let's say that you wish to analyse some data set, and -need `{dplyr}` and `{ggplot2}`. Let's also suppose that you use RStudio as your -IDE. With the `rix::rix()` function, you can easily generate the right -`default.nix` file. You need to provide the following inputs to `rix()`: - -- `r_ver`: the version of R required. Use "latest" for the latest version; -- `r_pkgs`: the required R packages. For example "dplyr"; -- `system_pkgs`: the required system packages, if needed. For example "quarto", or a Python interpreter; -- `git_pkgs`: list of git packages to add. See the example below; -- `ide`: the integrated development editor to use. For example "rstudio" if you want to use RStudio. Refer to the "Interactive work with {rix}" for more details; -- `path`: the path where to save the `default.nix` file. -- `overwrite`: whether to overwrite the `default.nix` file or not. -- `print`: whether to print the `default.nix` file to the console or not. - -In such a situation, you could create an environment with the following call to `rix()`: - -```{r} -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) -``` - -To start using this environment, open a console in the folder containing -`default.nix` and use the following Nix command: - -``` -nix-build -``` - -`nix-build` is a Nix command that builds an environment according to the -specifications found in a `default.nix` file. Once the environment is done -building, you should find a new file called `result` next to the `default.nix` -file. This file is a symlink to the software installed by Nix. To now use the -environment, type: - -``` -nix-shell -``` - -You can now start the RStudio provided by that environment by typing `rstudio`. -This will start a version of RStudio specific to this environment. If you -already had RStudio installed by using your operating system's installer, that -version of RStudio will not be able to interact with Nix environments. This is -because RStudio looks for R in certain specific paths that don't include any Nix -environments. This is not the case with other editors like Visual Studio Code or -Emacs. If you use Visual Studio Code, you can use the following call to `rix()`: - -```{r} -path_default_nix <- tempdir() - -rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "code", - project_path = path_default_nix, - overwrite = TRUE) -``` - -(note the value provided to the `ide` argument). - -This generates the following `default.nix` file: - -```{r, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -As you can see, specifying `ide = "code"` adds the `{languageserver}` package to -the list of packages that must be installed for this environment. This is -because Visual Studio Code requires this package to interact with R. This will -not install a Nix environment-specific version of Visual Studio Code. Now, -instead of typing `rstudio` in the Nix shell of your environment, type `code` -and this will start the Visual Studio Code you usually use. - -If you use another editor, like Emacs, then use `ide = "other"`, and start that -editor inside an activated Nix environment. - -For more details on interactive use, read the "Interactive use" vignette. - -## Running old projects with {rix} - -The example below shows how to create a `default.nix` with instructions to build -an environment with R version 4.2.1, the `{dplyr}` and `{janitor}` packages and -no specific IDE: - -```{r} -path_default_nix <- tempdir() - -rix(r_ver = "4.2.1", - r_pkgs = c("dplyr", "janitor"), - system_pkgs = c("quarto"), - git_pkgs = NULL, - ide = "other", - project_path = path_default_nix, - overwrite = TRUE) - -``` - -The file looks like this: - -```{r, echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -The first line is quite important, as it shows which *revision* of `nixpkgs` is -being used for this environment. The *revision* is the commit hash of that -particular release of `nixpkgs`, here: `79b3d4bcae8`. This revision of `nixpkgs` -is the one that shipped version 4.2.1 of R, so the `{dplyr}` and `{janitor}` -packages that will get installed will be the versions available in that revision -as well. This means that R versions and package versions are always coupled when -using Nix. However, if you need a specific version of R, but also a specific -version of a package that is not available in that particular Nix revision, one -solution is to install that package from Github. - -## Installing old packages archived on CRAN - -It is also possible to install an arbitrary version of a package that has -been archived on CRAN: - -```{r} -rix(r_ver = "4.2.1", - 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) -``` - -```{r} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -This feature should ideally be used sparingly. If you want to reconstruct an -environment as it was around 2019, use the version of R that was current at the -time. This will ensure that every package that gets installed is at a version -compatible with that version of R, which might not be the case if you need to -install a very old version of one particular package. - -## Installing packages from Github - -It is also possible to install packages from Github: - -```{r} -rix(r_ver = "4.2.1", - r_pkgs = c("dplyr", "janitor"), - system_pkgs = c("quarto"), - 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) - -``` - -```{r} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -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 -is also installed, from the main branch at commit `d617172447d`. - -## A complete example - -This example shows how all features of `{rix}` can work together: - -```{r} -rix(r_ver = "4.2.1", - r_pkgs = c("dplyr", "janitor", "AER@1.2-8"), - system_pkgs = c("quarto"), - 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 = "rstudio", - project_path = path_default_nix, - overwrite = TRUE) - -``` - -```{r} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - - -To learn more about using `{rix}` on a daily basis, read the [Interactive -use](https://b-rodrigues.github.io/rix/articles/interactive-use.html) vignette. diff --git a/dev/config_fusen.yaml b/dev/config_fusen.yaml index c607995b..095194b5 100644 --- a/dev/config_fusen.yaml +++ b/dev/config_fusen.yaml @@ -1,103 +1,181 @@ -build_envs.Rmd: - path: dev/build_envs.Rmd +1-getting_started.Rmd: + path: dev/1-getting_started.Rmd state: active - R: R/find_rev.R - tests: tests/testthat/test-find_rev.R - vignettes: [] + R: [] + tests: [] + vignettes: vignettes/1-getting-started.Rmd inflate: - flat_file: dev/build_envs.Rmd - vignette_name: .na + flat_file: dev/1-getting_started.Rmd + vignette_name: 1 - Getting started + open_vignette: true + check: true + document: true + overwrite: 'yes' +2a-linux_win.Rmd: + path: dev/2a-linux_win.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/2a-setting-up-and-using-rix-on-linux-and-windows.Rmd + inflate: + flat_file: dev/2a-linux_win.Rmd + vignette_name: 2a - Setting up and using rix on Linux and Windows + open_vignette: true + check: true + document: true + overwrite: 'yes' +2b-macos.Rmd: + path: dev/2b-macos.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/2b-setting-up-and-using-rix-on-macos.Rmd + inflate: + flat_file: dev/2b-macos.Rmd + vignette_name: 2b - Setting up and using rix on macOS + open_vignette: true + check: true + document: true + overwrite: 'yes' +3-building_envs_with_rix.Rmd: + path: dev/3-building_envs_with_rix.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/3-using-rix-to-build-project-specific-environments.Rmd + inflate: + flat_file: dev/3-building_envs_with_rix.Rmd + vignette_name: 3 - Using rix to build project specific environments + open_vignette: true + check: true + document: true + overwrite: 'yes' +4a-install_r_pkgs.Rmd: + path: dev/4a-install_r_pkgs.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/4a-installing-r-packages-in-a-nix-environment.Rmd + inflate: + flat_file: dev/4a-install_r_pkgs.Rmd + vignette_name: 4a - Installing R packages in a Nix environment + open_vignette: true + check: true + document: true + overwrite: 'yes' +4b-install_sys_pkgs.Rmd: + path: dev/4b-install_sys_pkgs.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/4b-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd + inflate: + flat_file: dev/4b-install_sys_pkgs.Rmd + vignette_name: 4b - Installing system tools and TexLive packages in a Nix environment open_vignette: true check: true document: true overwrite: 'yes' -building_envs_with_rix.Rmd: - path: dev/building_envs_with_rix.Rmd +5-interactive_use.Rmd: + path: dev/5-interactive_use.Rmd state: active R: [] tests: [] - vignettes: vignettes/building-reproducible-development-environments-with-rix.Rmd + vignettes: vignettes/5-interactive-use.Rmd inflate: - flat_file: dev/building_envs_with_rix.Rmd - vignette_name: Building reproducible development environments with rix + flat_file: dev/5-interactive_use.Rmd + vignette_name: 5 - Interactive use open_vignette: true check: true document: true overwrite: 'yes' -cicd.Rmd: - path: dev/cicd.Rmd +flat_build_envs.Rmd: + path: dev/flat_build_envs.Rmd + state: active + R: R/find_rev.R + tests: tests/testthat/test-find_rev.R + vignettes: [] + inflate: + flat_file: dev/flat_build_envs.Rmd + vignette_name: .na + open_vignette: true + check: true + document: true + overwrite: 'yes' +flat_cicd.Rmd: + path: dev/flat_cicd.Rmd state: active R: R/tar_nix_ga.R tests: [] vignettes: [] inflate: - flat_file: dev/cicd.Rmd + flat_file: dev/flat_cicd.Rmd vignette_name: .na open_vignette: true check: true document: true overwrite: 'yes' -cran_archive.Rmd: - path: dev/cran_archive.Rmd +flat_cran_archive.Rmd: + path: dev/flat_cran_archive.Rmd state: active R: R/detect_versions.R tests: tests/testthat/test-detect_versions.R vignettes: [] inflate: - flat_file: dev/cran_archive.Rmd + flat_file: dev/flat_cran_archive.Rmd vignette_name: .na open_vignette: true check: true document: true overwrite: 'yes' -data_doc.Rmd: - path: dev/data_doc.Rmd +flat_data_doc.Rmd: + path: dev/flat_data_doc.Rmd state: active R: R/included-datasets.R tests: [] vignettes: [] inflate: - flat_file: dev/data_doc.Rmd + flat_file: dev/flat_data_doc.Rmd vignette_name: .na open_vignette: true check: true document: true overwrite: 'yes' -get_os.Rmd: - path: dev/get_os.Rmd +flat_get_os.Rmd: + path: dev/flat_get_os.Rmd state: active R: R/detect_os.R tests: [] vignettes: [] inflate: - flat_file: dev/get_os.Rmd + flat_file: dev/flat_get_os.Rmd vignette_name: .na open_vignette: true check: true document: true overwrite: 'yes' -interactive_use.Rmd: - path: dev/interactive_use.Rmd +flat_save_r_nix_revs.Rmd: + path: dev/flat_save_r_nix_revs.Rmd state: active R: [] tests: [] - vignettes: vignettes/interactive-use.Rmd + vignettes: vignettes/developers-vignette-save-the-nix-package-versions-data.Rmd inflate: - flat_file: dev/interactive_use.Rmd - vignette_name: Interactive use + flat_file: dev/flat_save_r_nix_revs.Rmd + vignette_name: 'Developers Vignette: Save the Nix Package Versions data' open_vignette: true check: true document: true overwrite: 'yes' -run_code_in_nix_from_r.Rmd: - path: dev/running_r_or_shell_code_in_nix_from_r.Rmd +flat_zzz.Rmd: + path: dev/flat_zzz.Rmd state: active - R: [] + R: R/zzz.R tests: [] - vignettes: vignettes/running-r-or-shell-code-in-nix-from-r.Rmd + vignettes: [] inflate: - flat_file: dev/running_r_or_shell_code_in_nix_from_r.Rmd - vignette_name: Running R or shell code in Nix from R + flat_file: dev/flat_zzz.Rmd + vignette_name: .na open_vignette: true check: true document: true @@ -107,10 +185,10 @@ literate_programming.Rmd: state: active R: [] tests: [] - vignettes: vignettes/building-an-environment-for-literate-programming.Rmd + vignettes: vignettes/advanced-topic-building-an-environment-for-literate-programming.Rmd inflate: flat_file: dev/literate_programming.Rmd - vignette_name: Building an environment for literate programming + vignette_name: 'Advanced topic: Building an environment for literate programming' open_vignette: true check: true document: true @@ -120,50 +198,37 @@ pkgs_with_remotes.Rmd: state: active R: [] tests: [] - vignettes: vignettes/handling-packages-with-remote-dependencies.Rmd + vignettes: vignettes/advanced-topic-handling-packages-with-remote-dependencies.Rmd inflate: flat_file: dev/pkgs_with_remotes.Rmd - vignette_name: Handling packages with remote dependencies + vignette_name: 'Advanced topic: Handling packages with remote dependencies' open_vignette: true check: true document: true - overwrite: ask + overwrite: 'yes' raps_with_nix.Rmd: path: dev/raps_with_nix.Rmd state: active R: [] tests: [] - vignettes: vignettes/reproducible-analytical-pipelines-with-nix.Rmd + vignettes: vignettes/advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd inflate: flat_file: dev/raps_with_nix.Rmd - vignette_name: Reproducible Analytical Pipelines with Nix + vignette_name: 'Advanced topic: Reproducible Analytical Pipelines with Nix' open_vignette: true check: true document: true overwrite: 'yes' -save_r_nix_revs.Rmd: - path: dev/save_r_nix_revs.Rmd +subshells.Rmd: + path: dev/subshells.Rmd state: active R: [] tests: [] - vignettes: vignettes/save-the-nix-package-versions-data.Rmd + vignettes: vignettes/advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd inflate: - flat_file: dev/save_r_nix_revs.Rmd - vignette_name: Save the Nix Package Versions data + flat_file: dev/subshells.Rmd + vignette_name: 'Advanced topic: Running R or Shell Code in Nix from R' open_vignette: true check: true document: true overwrite: 'yes' -zzz.Rmd: - path: dev/zzz.Rmd - state: active - R: R/zzz.R - tests: [] - vignettes: [] - inflate: - flat_file: dev/zzz.Rmd - vignette_name: .na - open_vignette: true - check: true - document: false - overwrite: 'yes' diff --git a/dev/config_fusen.yaml-old b/dev/config_fusen.yaml-old new file mode 100644 index 00000000..c607995b --- /dev/null +++ b/dev/config_fusen.yaml-old @@ -0,0 +1,169 @@ +build_envs.Rmd: + path: dev/build_envs.Rmd + state: active + R: R/find_rev.R + tests: tests/testthat/test-find_rev.R + vignettes: [] + inflate: + flat_file: dev/build_envs.Rmd + vignette_name: .na + open_vignette: true + check: true + document: true + overwrite: 'yes' +building_envs_with_rix.Rmd: + path: dev/building_envs_with_rix.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/building-reproducible-development-environments-with-rix.Rmd + inflate: + flat_file: dev/building_envs_with_rix.Rmd + vignette_name: Building reproducible development environments with rix + open_vignette: true + check: true + document: true + overwrite: 'yes' +cicd.Rmd: + path: dev/cicd.Rmd + state: active + R: R/tar_nix_ga.R + tests: [] + vignettes: [] + inflate: + flat_file: dev/cicd.Rmd + vignette_name: .na + open_vignette: true + check: true + document: true + overwrite: 'yes' +cran_archive.Rmd: + path: dev/cran_archive.Rmd + state: active + R: R/detect_versions.R + tests: tests/testthat/test-detect_versions.R + vignettes: [] + inflate: + flat_file: dev/cran_archive.Rmd + vignette_name: .na + open_vignette: true + check: true + document: true + overwrite: 'yes' +data_doc.Rmd: + path: dev/data_doc.Rmd + state: active + R: R/included-datasets.R + tests: [] + vignettes: [] + inflate: + flat_file: dev/data_doc.Rmd + vignette_name: .na + open_vignette: true + check: true + document: true + overwrite: 'yes' +get_os.Rmd: + path: dev/get_os.Rmd + state: active + R: R/detect_os.R + tests: [] + vignettes: [] + inflate: + flat_file: dev/get_os.Rmd + vignette_name: .na + open_vignette: true + check: true + document: true + overwrite: 'yes' +interactive_use.Rmd: + path: dev/interactive_use.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/interactive-use.Rmd + inflate: + flat_file: dev/interactive_use.Rmd + vignette_name: Interactive use + open_vignette: true + check: true + document: true + overwrite: 'yes' +run_code_in_nix_from_r.Rmd: + path: dev/running_r_or_shell_code_in_nix_from_r.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/running-r-or-shell-code-in-nix-from-r.Rmd + inflate: + flat_file: dev/running_r_or_shell_code_in_nix_from_r.Rmd + vignette_name: Running R or shell code in Nix from R + open_vignette: true + check: true + document: true + overwrite: 'yes' +literate_programming.Rmd: + path: dev/literate_programming.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/building-an-environment-for-literate-programming.Rmd + inflate: + flat_file: dev/literate_programming.Rmd + vignette_name: Building an environment for literate programming + open_vignette: true + check: true + document: true + overwrite: 'yes' +pkgs_with_remotes.Rmd: + path: dev/pkgs_with_remotes.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/handling-packages-with-remote-dependencies.Rmd + inflate: + flat_file: dev/pkgs_with_remotes.Rmd + vignette_name: Handling packages with remote dependencies + open_vignette: true + check: true + document: true + overwrite: ask +raps_with_nix.Rmd: + path: dev/raps_with_nix.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/reproducible-analytical-pipelines-with-nix.Rmd + inflate: + flat_file: dev/raps_with_nix.Rmd + vignette_name: Reproducible Analytical Pipelines with Nix + open_vignette: true + check: true + document: true + overwrite: 'yes' +save_r_nix_revs.Rmd: + path: dev/save_r_nix_revs.Rmd + state: active + R: [] + tests: [] + vignettes: vignettes/save-the-nix-package-versions-data.Rmd + inflate: + flat_file: dev/save_r_nix_revs.Rmd + vignette_name: Save the Nix Package Versions data + open_vignette: true + check: true + document: true + overwrite: 'yes' +zzz.Rmd: + path: dev/zzz.Rmd + state: active + R: R/zzz.R + tests: [] + vignettes: [] + inflate: + flat_file: dev/zzz.Rmd + vignette_name: .na + open_vignette: true + check: true + document: false + overwrite: 'yes' diff --git a/dev/build_envs.Rmd b/dev/flat_build_envs.Rmd similarity index 99% rename from dev/build_envs.Rmd rename to dev/flat_build_envs.Rmd index f760cdd7..7ce2731d 100644 --- a/dev/build_envs.Rmd +++ b/dev/flat_build_envs.Rmd @@ -18,6 +18,8 @@ You need to run the 'description' chunk in the '0-dev_history.Rmd' file before c pkgload::load_all(export_all = FALSE) ``` +# Main functions + This function takes an R version as an input and returns the Nix revision that provides it: ```{r function-find_rev} diff --git a/dev/cicd.Rmd b/dev/flat_cicd.Rmd similarity index 100% rename from dev/cicd.Rmd rename to dev/flat_cicd.Rmd diff --git a/dev/cran_archive.Rmd b/dev/flat_cran_archive.Rmd similarity index 100% rename from dev/cran_archive.Rmd rename to dev/flat_cran_archive.Rmd diff --git a/dev/data_doc.Rmd b/dev/flat_data_doc.Rmd similarity index 100% rename from dev/data_doc.Rmd rename to dev/flat_data_doc.Rmd diff --git a/dev/get_os.Rmd b/dev/flat_get_os.Rmd similarity index 100% rename from dev/get_os.Rmd rename to dev/flat_get_os.Rmd diff --git a/dev/save_r_nix_revs.Rmd b/dev/flat_save_r_nix_revs.Rmd similarity index 84% rename from dev/save_r_nix_revs.Rmd rename to dev/flat_save_r_nix_revs.Rmd index 2d9e9daf..97cee345 100644 --- a/dev/save_r_nix_revs.Rmd +++ b/dev/flat_save_r_nix_revs.Rmd @@ -1,10 +1,12 @@ --- -title: "Save the Nix Package Versions data" +title: "Developer Vignette: Save the Nix Package Versions data" output: html_document editor_options: chunk_output_type: console --- +This vignette is only needed for the developers of `{rix}`. + To install old versions of R, specific Nix revisions must be used. This tool [Nix Package Versions](https://lazamar.co.uk/nix-versions/) provides a simple web-interface to look for packages and get their revisions. diff --git a/dev/zzz.Rmd b/dev/flat_zzz.Rmd similarity index 100% rename from dev/zzz.Rmd rename to dev/flat_zzz.Rmd diff --git a/dev/interactive_use.Rmd b/dev/interactive_use.Rmd deleted file mode 100644 index 016644e2..00000000 --- a/dev/interactive_use.Rmd +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: "Interactive use" -output: html_document -editor_options: - chunk_output_type: console - markdown: - wrap: 80 ---- - -## Introduction - -This vignette describes interactive use of environments built with `{rix}` using -a GUI editor like RStudio. I will discuss two scenarios: one in which you -already have R and RStudio installed on your operating system using the usual -installation method for your operating system, and another in which you used Nix -to install R and RStudio (or any other IDE). - -## Scenario 0: you installed nix and want to build from an expression using {rix} - -We have a little helper `rix::nix_build()` which calls `nix-build` from R. All -you need is nix installed, and the curl command line utility or {curl}, its -interface from R. Here is an example to get the nix expression that can use -to build the "latest" R version available from nix and the development version -of {rix} from GitHub. - -```{sh, eval = FALSE} -curl -sl -o default.nix https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix -``` - -Then open an R session from terminal located in your project root folder. - -```{r, eval = FALSE} -nix_build(project_path = ".", exec_mode = "non-blocking") -``` - -This will build your project and stream messages and errors back in your -R console. - -## Scenario 1: you installed R and RStudio as usual - -Let's suppose that you are already running R and RStudio and that you wish to -start using `{rix}` to define reproducible environments for your new projects -starting today. These environments will get built using the Nix package manager -and will not only include the required R packages for your project but also a -specific version of R, and any required system-level dependency as well. If you -are used to using RStudio, then you also need to install RStudio using Nix in -these project-specific environments. To run a project-specific version of -RStudio and R, you will first need to create a `default.nix` file and build the -environment defined therein using Nix. Once this is done, you then need to -activate the environment before running this project-specific version of -RStudio. Suppose for example that you generated a `default.nix` file for a -project called "kmeans", and suppose that this project is in the following path: -`~/Documents/kmeans` (on Windows it would be something like -`C:\Users\Billy\Documents\kmeans`). Navigate to that folder using your terminal, -and then run `nix-shell`. You will then be *dropped into* a Nix shell. From -there you can type `rstudio` to run this project specific version of RStudio -with all the packages. You can then work on it as usual. - -You can also define a shortcut to a project that will take care of activating -the environment and launching rstudio. For example, you could define a bash -alias like this: - - alias kmeans='nix-shell ~/Documents/kmeans/default.nix --run rstudio - -which would then execute RStudio in the right project by simply typing `kmeans` -in a terminal. It's also possible to create an executable script that you can -save in your PATH: - - #!/usr/bin/env nix-shell - #!nix-shell /home/Billy/Document/kmeans/default.nix -i bash - rstudio - -Name this script something like `kmeans_project`, make it executable (using -`chmod +x kmeans_project`), and now you can run RStudio within this environment -from anywhere. - -## Scenario 2: you install R and RStudio using Nix - -If you don't have R installed you cannot use the `{rix}` package to generate new -expressions. In this case you might consider installing Nix first, and then -running the following command inside your terminal to get dropped into a -temporary Nix shell, which you can then use to generate new `default.nix` files: - - nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" - -Running the command above will download R and `{rix}` and then start an R -session inside your terminal. You can now run something like this: - - rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "rstudio", - project_path = ".", # change to a project's path - overwrite = TRUE) - -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`. - -## Other IDEs - -Visual Studio Code and Emacs have been tested and unlike RStudio, you can use -the version of either VS Code or Emacs that you already have installed on your -system. But there's nothing stopping you from installing a project-specific -version of VS Code or Emacs as well. Configuration and settings should be -accessible across every version from every environment, since these are globally -defined at the level of your system. diff --git a/dev/literate_programming.Rmd b/dev/literate_programming.Rmd index 0841e8e6..668d5fad 100644 --- a/dev/literate_programming.Rmd +++ b/dev/literate_programming.Rmd @@ -1,5 +1,5 @@ --- -title: "Building an environment for literate programming" +title: "Advanced topic: Building an environment for literate programming" output: html_document editor_options: chunk_output_type: console @@ -52,9 +52,11 @@ with this small version, you can click [here](https://search.nixos.org/packages?channel=unstable&show=texlive.combined.scheme-small&from=0&size=50&sort=relevance&type=packages&query=scheme-small). We start by adding the `amsmath` package then build the environment using: -```{r, eval = F} -nix_build() ``` +nix-build +``` + +from a terminal, or `nix_build()` from an interactive R session. Then, drop into the Nix shell with `nix-shell`, and run `quarto add quarto-journals/jss`. This will install the template linked above. Then, in the @@ -251,7 +253,7 @@ document. This is in contrast to before where we used `quarto add quarto-journals/jss` to install the template. Doing this interactively makes our project not reproducible because if we compile our Quarto doc today, we would be using the template as it is today, but if we compile the document in 6 months, -then we would be using the template as it would be in 6 months (I should say +then we would be using the template as it would be in 6 months (we should say that it is possible to install specific releases of Quarto templates using following notation: `quarto add quarto-journals/jss@v0.9.2` so this problem can be mitigated). @@ -338,5 +340,4 @@ This vignette showed two approaches, both have their merits: the first approach that is more interactive is useful while writing the document. You get access to a shell and can work on the document and compile it quickly. The second approach is more useful once the document is ready and you want to have a way of quickly -rebuilding it for reproducibility purposes. This approach should also be quite -useful in a CI/CD environment. +rebuilding it for reproducibility purposes. diff --git a/dev/pkgs_with_remotes.Rmd b/dev/pkgs_with_remotes.Rmd index 2997805d..d6e01b63 100644 --- a/dev/pkgs_with_remotes.Rmd +++ b/dev/pkgs_with_remotes.Rmd @@ -1,5 +1,5 @@ --- -title: "Handling packages with remote dependencies" +title: "Advanced topic: Handling packages with remote dependencies" output: html_document editor_options: chunk_output_type: console @@ -7,21 +7,22 @@ editor_options: ## Introduction -Packages on CRAN must have their dependencies on either CRAN or Bioconductor, -but not on Github. However, there are many packages available on Github that -never get published on CRAN, and some of these packages may even depend on other -packages that are also only available on Github. `{rix}` makes it possible to -install packages from Github, but in case one of the package's dependencies has -also only been released on Github, building the Nix environment will fail. This -is because Nix will be looking for these packages on `nixpkgs`, but only -packages released on CRAN and Bioconductor are available through `nixpkgs`. This -vignette explains how to install such a packages with dependencies on Github. +Packages published on CRAN must have their dependencies on either CRAN or +Bioconductor, but not on GitHub. However, there are many packages available on +GitHub that never get published on CRAN, and some of these packages may even +depend on other packages that are also only available on GitHub. `{rix}` makes +it possible to install packages from GitHub, but in case one of the package's +dependencies has also only been released on GitHub, building the Nix environment +will fail. This is because Nix will be looking for these packages on `nixpkgs`, +but only packages released on CRAN and Bioconductor are available through +`nixpkgs`. This vignette explains how to install such a packages that have +dependencies only available on GitHub. ## The {lookup} package As an example we are going to use the [{lookup}](https://github.com/jimhester/lookup) package which has only been -released on Github. [Here is the +released on GitHub. [Here is the repository](https://github.com/jimhester/lookup). This package comes with the `lookup()` function which makes it possible to check the source code of any function from a loaded package, even if the source of that function is in C or @@ -55,7 +56,7 @@ error: attribute 'highlite' missing ## Building remote dependencies `{highlite}` is a dependency of [{lookup}](https://github.com/jimhester/lookup) -that is only available on CRAN. This can be checked by looking at the +that is only available on GitHub. This can be checked by looking at the `DESCRIPTION` file of [{lookup}](https://github.com/jimhester/lookup): ``` @@ -65,11 +66,11 @@ Remotes: hadley/memoise ``` -We see that there are actually three packages that come from Github: but -`{gh}` and `{memoise}` have in the meantime been released on CRAN, which means -that they are also available through `nixpkgs`. We have to deal with `{highlite}` -however. Doing so is fairly easy: first, create a new expression using `{rix}` -to install `{highlite}`: +We see that there are actually three packages that come from GitHub: but `{gh}` +and `{memoise}` have in the meantime been released on CRAN, which means that +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}`: ``` rix(r_ver = "latest", @@ -166,8 +167,8 @@ propagatedBuildInputs = builtins.attrValues { Building the expression now succeeds. -We know that this is quite tedious, but at the moment there are no plans to -make `{rix}` handle remote dependencies automatically. This is for mainly three +We know that this is quite tedious, but at the moment there are no plans to make +`{rix}` handle remote dependencies automatically. This is for mainly three reasons: - packages with remote dependencies are rare, and never on CRAN on Bioconductor; diff --git a/dev/raps_with_nix.Rmd b/dev/raps_with_nix.Rmd index 93ad9a0e..d8a146a1 100644 --- a/dev/raps_with_nix.Rmd +++ b/dev/raps_with_nix.Rmd @@ -1,5 +1,5 @@ --- -title: "Reproducible Analytical Pipelines with Nix" +title: "Advanced topic: Reproducible Analytical Pipelines with Nix" output: html_document editor_options: chunk_output_type: console @@ -14,9 +14,9 @@ packages. ## An example of a reproducible analytical pipeline using Nix -Suppose that I used `{targets}` to build a pipeline for a project and that I did -so using a tailor-made Nix environment. Here is the call to `rix()` that I used -to build that environment: +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} path_default_nix <- tempdir() @@ -42,15 +42,15 @@ cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") 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 I developing specifically for this project. -Because it is on Github, it gets installed using the `buildRPackage` function -from Nix. I can use this environment to work on my project, or to launch my -`{targets}` pipeline. [This Github +packages, which is a package that is hosted on GitHub only with some data and +useful functions for the project. Because it is on Github, it gets installed +using the `buildRPackage` function from Nix. You can use this environment to +work on you project, or to launch a `{targets}` pipeline. [This Github repository](https://github.com/b-rodrigues/nix_targets_pipeline/tree/master) contains the finalized project. -If you use `{targets}` you could execute the pipeline in the environment by -running in a terminal: +On your local machine, you could execute the pipeline in the environment by +running this in a terminal: ``` cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'" @@ -59,21 +59,27 @@ 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: -``` -... -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 ]; - shellHook = '' Rscript -e "targets::tar_make()" ''; -} +```{r, eval = FALSE} +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", + shell_hook = "Rscript -e 'targets::tar_make()'", + project_path = path_default_nix, + overwrite = TRUE) ``` Now, each time you drop into the Nix shell for that project using `nix-shell`, -the pipeline gets automatically executed. +the pipeline gets automatically executed. `{rix}` also features a function +called `tar_nix_ga()` that adds a GitHub Actions workflow file to make the +pipeline run automatically on GitHub Actions. The GitHub repository linked above +has such a file, so each time changes get pushed, the pipeline runs on Github +Actions and the results are automatically pushed to a branch called +`targets-runs`. See the workflow file +[here](https://github.com/b-rodrigues/nix_targets_pipeline/blob/master/.github/workflows/run-pipeline.yaml). +This feature is very heavily inspired and adapted from the +`targets::github_actions()` function. diff --git a/dev/running_r_or_shell_code_in_nix_from_r.Rmd b/dev/subshells.Rmd similarity index 99% rename from dev/running_r_or_shell_code_in_nix_from_r.Rmd rename to dev/subshells.Rmd index 3f579b4e..ca2d772c 100644 --- a/dev/running_r_or_shell_code_in_nix_from_r.Rmd +++ b/dev/subshells.Rmd @@ -1,5 +1,5 @@ --- -title: "Running R or Shell Code in Nix from R" +title: "Advanced topic: Running R or Shell Code in Nix from R" output: html_document editor_options: chunk_output_type: console diff --git a/tests/testthat/test-detect_versions.R b/tests/testthat/test-detect_versions.R index 26c0fed2..458c55cb 100644 --- a/tests/testthat/test-detect_versions.R +++ b/tests/testthat/test-detect_versions.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/cran_archive.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_cran_archive.Rmd: do not edit by hand testthat::expect_equal( detect_versions(c("dplyr", "tidyr")), diff --git a/tests/testthat/test-find_rev.R b/tests/testthat/test-find_rev.R index d9fbbe89..c2853d0b 100644 --- a/tests/testthat/test-find_rev.R +++ b/tests/testthat/test-find_rev.R @@ -1,4 +1,4 @@ -# WARNING - Generated by {fusen} from dev/build_envs.Rmd: do not edit by hand +# WARNING - Generated by {fusen} from dev/flat_build_envs.Rmd: do not edit by hand testthat::expect_equal( find_rev("4.2.2"), diff --git a/vignettes/1-getting-started.Rmd b/vignettes/1-getting-started.Rmd new file mode 100644 index 00000000..0f378283 --- /dev/null +++ b/vignettes/1-getting-started.Rmd @@ -0,0 +1,129 @@ +--- +title: "1 - Getting started" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{1-getting-started} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +## The Nix package manager + +Nix is a package manager that can be installed on your computer (regardless of +OS) and can be used to install software like with any other package manager. If +you're familiar with the Ubuntu Linux distribution, you likely have used +`apt-get` to install software. On macOS, you may have used `homebrew` for +similar purposes. Nix functions in a similar way, but has many advantages over +classic package managers. The main advantage of Nix, at least for our purposes, +is that its repository of software is huge. As of writing, it contains more than +80.000 packages, and the entirety of CRAN and Bioconductor is available through +Nix's repositories. This means that using Nix, it is possible to install not +only R, but also all the packages required for your project. The obvious +question is why use Nix instead of simply installing R and R packages as usual. +The answer is that Nix makes sure to install every dependency of any package, up +to required system libraries. For example, the `{xlsx}` package requires the +Java programming language to be installed on your computer to successfully +install. This can be difficult to achieve, and `{xlsx}` bullied many R +developers throughout the years (especially those using a Linux distribution, +`sudo R CMD javareconf` still plagues my nightmares). But with Nix, it suffices +to declare that we want the `{xlsx}` package for our project, and Nix figures +out automatically that Java is required and installs and configures it. It all +just happens without any required intervention from the user. The second +advantage of Nix is that it is possible to *pin* a certain *revision* of the Nix +packages' repository (called `nixpkgs`) for our project. Pinning a revision +ensures that every package that Nix installs will always be at exactly the same +versions, regardless of when in the future the packages get installed. + + +## rix workflow + +The idea of `{rix}` is for you to declare the environment you need using the +provided `rix()` function. `rix()` is the package’s main function and generates +a file called `default.nix` which is then used by the Nix package manager to +build that environment. Ideally, you would set up such an environment for each +of your projects. You can then use this environment to either work +interactively, or run R scripts. It is possible to have as many environments as +projects, and software that is common to environments will simply be re-used and +not get re-installed to save space. Environments are isolated for each other, +but can still interact with your system's files, unlike with Docker where a +volume must be mounted. Environments can also interact with the software +installed on your computer through the usual means, which can sometimes lead to +issues. We have provided functions and documentation to avoid this, so take your +time read through the vignettes and you should be fine. + +`rix()` has several arguments: + +- the R version you need for your project; +- a list of R packages that your project needs; +- an optional list of additional software (for example a Python interpreter, or Quarto); +- an optional list with packages to install from Github; +- an optional list of LaTeX packages; +- whether you want to use RStudio as an IDE for your project (or VS Code, or another environment); +- the path to save the `default.nix` file (by default the current working directory) + +For example: + + +```{r eval = FALSE} +rix(r_ver = "latest", + r_pkgs = c("dplyr", "chronicler"), + ide = "other") +``` + +The call above writes a `default.nix` file in the current working directory. +This `default.nix` can in turn be used by Nix to build an environment containing +the latest version of R, with the `{dplyr}` and `{chronicler}` packages. + +Take note of the `ide = "other"` argument: this argument, and the values it +can take, are further discussed in the vignette `vignette("5-interactive_use")` +but continue reading this vignette and then vignettes numbered by a "4". + + +### Using default.nix files + +The Nix package manager can be used to build reproducible development +environments according to the specifications found in the generated +`default.nix` files, which contain a Nix *expression*. An *expression* is Nix +jargon for a function with multiple inputs and one output, this output being our +development environment. `{rix}` does not require Nix to be installed to +generate valid expressions (but does require an internet connection), so you +could generate expressions and use them on other machines. To actually build an +environment using a `default.nix` file, go to where you chose to write it +(ideally in a new, empty folder that will be the root folder of your project) +and use the Nix package manager to build the environment. Call the following +function in a terminal: + +``` +nix-build +``` + +Once Nix is done building the environment, you can start working on it +interactively by using the following command in a terminal emulator (not the R +console): + +``` +nix-shell +``` + +You will *drop* into a Nix shell which provides the installed software. + +Now that you know more about Nix and `{rix}`, it is time to get these tools +installed on your system. + +- If you’re running either Linux or Windows, read the Linux or Windows vignette: `vignette("2a-setting-up-and-using-rix-on-linux-and-windows")` +- If you’re running macOS, read the macOS vignette: `vignette("2b-setting-up-and-using-rix-on-macos")` + + diff --git a/vignettes/2a-setting-up-and-using-rix-on-linux-and-windows.Rmd b/vignettes/2a-setting-up-and-using-rix-on-linux-and-windows.Rmd new file mode 100644 index 00000000..9999e852 --- /dev/null +++ b/vignettes/2a-setting-up-and-using-rix-on-linux-and-windows.Rmd @@ -0,0 +1,173 @@ +--- +title: "2a - Setting up and using rix on Linux and Windows" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{2a-setting-up-and-using-rix-on-linux-and-windows} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +*This vignette will discuss Linux and Windows-specific topics. If you're not +using either of these systems, you can ignore this vignette, and read the +`vignette("2b-setting-up-and-using-rix-on-macos")` +vignette instead.* + + +## Introduction + +When it comes to Nix, there are really only two supported operating systems: +macOS and Linux distributions. Windows is "supported" because it is actually +running Linux thanks to WSL2. In practice this means that Linux distributions +and Windows can be considered one system, and macOS another, separate, system. +Because Windows is really running Linux under the hood thanks to WSL2, this +means that WSL2 needs to be running on your Windows system before you attempt to +install Nix. But it is important to know that you can run `{rix}` even if you +don't have Nix installed, which means you can generate Nix expressions, you +just can't build them. + + +### Windows pre-requisites + +If you are on Windows, you need the Windows Subsystem for Linux 2 (WSL2) to run +Nix. If you are on a recent version of Windows 10 or 11, you can simply run this +as an administrator in PowerShell: + +``` +wsl --install +``` + +You can find further installation notes at [this official MS +documentation](https://learn.microsoft.com/en-us/windows/wsl/install). + +We recommend to activate systemd in Ubuntu WSL2, mainly because this supports +other users than `root` running Nix. To set this up, please do as outlined +[this official Ubuntu blog entry](https://ubuntu.com/blog/ubuntu-wsl-enable-systemd): + +```sh + +# in WSL2 Ubuntu shell + +sudo -i +nano /etc/wsl.conf + +# add this entry + +[boot] +systemd=true + +# then restart running instance from PowerShell + +wsl --shutdown + +# relaunch Ubuntu WSL2 + +``` + +Afterwards, you can install Nix like business as usual. You can proceed with the +Determinate Systems installer. + + +## Installing Nix + +You can use `{rix}` to generate Nix expressions even if you don't have Nix +installed on your system, but obviously, you need to install Nix if you actually +want to build the defined development environment and use them. Installing (and +uninstalling) Nix is quite simple, thanks to the installer from [Determinate +Systems](https://determinate.systems/posts/determinate-nix-installer), a company +that provides services and tools built on Nix. Simply open a terminal and run +the following line (on Windows, if you cannot or have decided not to activate +systemd, then you have to append `--init none` to the command. You can find more +details about this on [The Determinate Nix +Installer page](https://github.com/DeterminateSystems/nix-installer)): + + +```{sh eval = FALSE} +curl --proto '=https' --tlsv1.2 -sSf \ + -L https://install.determinate.systems/nix | \ + sh -s -- install +``` + +Once you have Nix installed, you can build the expressions you generate with `{rix}`! + +On Linux, once Nix is installed, all the software that will be installed through +Nix will be saved to the `/nix` directory on the root partition. It is common +for Linux users to have a separate partition for `/`, which may be small. +Complete development environments built with Nix can take up much space, so if +the available space on your root partition is limited, we advise you to mount the +`/nix` folder on another partition with more space (for example, a secondary +hard drive). For this, edit `/etc/fstab` and add the following line at the end: + +``` +/home/path_to/nix /nix none bind 0 0 +``` + +This will map `/nix` to `/home/path_to/nix` which can be on a larger partition. +If you have enough space on your root partition, you can ignore the above +instructions. + + +## What if you don't have R already installed? + +If you have successfully installed Nix, but don't have yet R installed on your +system, you could install R as you would usually do on your operating system, +and then install the `{rix}` package, and from there, generated project-specific +expressions and build them. But you could also install R using Nix. Running the +following line in a terminal will drop you in an interactive R session that you +can use to start generating expressions: + +``` +nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" +``` + +This should immediately start an R session inside your terminal. You can now run +something like this: + +``` +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "other", + project_path = ".", + overwrite = TRUE) +``` + +to generate a `default.nix`, and then use that file to generate an environment +with R, `{dplyr}` and `{ggplot2}`. If you need to add packages for your project, +rerun the command above, but add the needed packages to `r_pkgs`. This is +detailled in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")` and +`vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`. + + +## Generating expressions + +Once you have R installed, either through the usual installer for your operating +system, or through Nix as explained previously, you can now start building +project-specific development environments. + +Start an R session, and install `{rix}` if that's not already done. Because +`{rix}` is not yet on CRAN, the easiest way is to install it from its +r-universe: + + +```{r eval = FALSE} +install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", + "https://cloud.r-project.org")) +``` + +You can then use the `{rix}` package to generate expressions. Consult the +next vignette `vignette("3-using-rix-to-build-project-specific-environments")` to learn more. + diff --git a/vignettes/2b-setting-up-and-using-rix-on-macos.Rmd b/vignettes/2b-setting-up-and-using-rix-on-macos.Rmd new file mode 100644 index 00000000..a4df4e5d --- /dev/null +++ b/vignettes/2b-setting-up-and-using-rix-on-macos.Rmd @@ -0,0 +1,155 @@ +--- +title: "2b - Setting up and using rix on macOS" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{2b-setting-up-and-using-rix-on-macos} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +*This vignette will discuss macOS-specific topics. If you're not using macOS, you +can ignore this vignette, and read the +`vignette("2a-setting-up-and-using-rix-on-linux-and-windows")` +vignette instead.* + + +## Introduction + +When it comes to Nix, there are really only two supported operating systems: macOS +and Linux distributions. Windows is "supported" because it is actually 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 +idiosyncracies. This vignette details these. + + +## Installing Nix + +You can use `{rix}` to generate Nix expressions even if you don't have Nix installed +on your system, but obviously, you need to install Nix if you actually want to +build the defined development environment and use them. Installing (and uninstalling) +Nix is quite simple, thanks to the installer from +[Determinate +Systems](https://determinate.systems/posts/determinate-nix-installer), a company +that provides services and tools built on Nix. Simply open a terminal and run the following +line: + + +```{sh eval = FALSE} +curl --proto '=https' --tlsv1.2 -sSf \ + -L https://install.determinate.systems/nix | \ + sh -s -- install +``` + +Once you have Nix installed, you can build the expressions you generate with `{rix}`! + + +## What if you don't have R already installed? + +If you have successfully installed Nix, but don't have yet R installed on your +system, you could install R as you would usually do on your operating system, +and then install the `{rix}` package, and from there, generated project-specific +expressions and build them. But you could also install R using Nix. Running the +following line in a terminal will drop you in an interactive R session that you +can use to start generating expressions: + +``` +nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" +``` + +This should immediately start an R session inside your terminal. You can now run +something like this: + +``` +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "other", + project_path = ".", + overwrite = TRUE) +``` + +to generate a `default.nix`, and then use that file to generate an environment +with R, `{dplyr}` and `{ggplot2}`. If you need to add packages for your project, +rerun the command above, but add the needed packages to `r_pkgs`. This is +detailled in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")` and +`vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`. + + +## Generating expressions + +Once you have R installed, either through the usual installer for your operating +system, or through Nix as explained previously, you can now start building +project-specific development environments. + +On macOS, generating expressions works just like on Linux and Windows. Start an +R session, and install `{rix}` if that's not already done. Because `{rix}` is +not yet on CRAN, the easiest way is to install it from its r-universe: + + +```{r eval = FALSE} +install.packages("rix", repos = c("https://b-rodrigues.r-universe.dev", + "https://cloud.r-project.org")) +``` + +You can then use the `{rix}` package to generate expressions. Consult the +next vignette `vignette("3-using-rix-to-build-project-specific-environments")` to learn more. + + +## More macOS specificities + +### Shared libraries issue + +When using environments built with Nix on macOS, you might get error messages +refering to "shared libraries", which indicate that your user library of R +packages is interfering with the project-specific Nix environment. In this case, +you might want to set up a project-specific `.Rprofile` using `rix::rix_init()`. +This function generates an `.Rprofile` file on the root of your project and +ensures that the Nix environment only loads R packages from its own +project-specific library. This should solve the issue. + + +### RStudio and other development interfaces on macOS + +As of writing, RStudio cannot be installed through `nixpkgs` for macOS, and if +you wish to use RStudio with a Nix environment, you have to install it through +`nixpkgs`. This means that it is impossible to use RStudio and a Nix environment +on macOS. When you try to generate an expression with `ide = +"rstudio"` on macOS, this will raise a warning. Here are the options you have: + +- ignore the warning, because the environment will be built on a Linux + distribution (even though you generated the expression on macOS) and used on a + Linux distribution; +- change the `ide =` argument to either `"other"` or `"code"`. Use `"code"` if + you want to use VS Code and `"other"` for any other editor, like Vim or Emacs. + These other editors don't need to be installed through `nixpkgs` to use Nix environments, + unlike RStudio; +- if you're working on a pipeline with the `{targets}` package, you could run it + on Github Actions. This means you could work on the code on RStudio outside + of the Nix environment, as the code will only be executed on Github Actions runners. See this + vignette `vignette("advanced-topic-reproducible-analytical-pipelines-with-nix")` for further details; +- work on your project as usual, using your usual installation of R and RStudio, + but generate a `default.nix` at the end with `ide = "other"` with the right + version of R for reproducibility purposes; +- use subshells to execute only the code you need to run in a specific + environment. See this vignette `vignette("advanced-topic-running-r-or-shell-code-in-nix-from-r")`; +- help us package RStudio for macOS on `nixpgs`. See + [https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/rstudio/default.nix](the + expression for RStudio). + +We recommend you continue with the next vignette before tackling the more advanced +topics listed above: `vignette("3-using-rix-to-build-project-specific-environments")`. + diff --git a/vignettes/3-using-rix-to-build-project-specific-environments.Rmd b/vignettes/3-using-rix-to-build-project-specific-environments.Rmd new file mode 100644 index 00000000..33e41df7 --- /dev/null +++ b/vignettes/3-using-rix-to-build-project-specific-environments.Rmd @@ -0,0 +1,176 @@ +--- +title: "3 - Using rix to build project specific environments" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{3-using-rix-to-build-project-specific-environments} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +## Project-specific Nix environments + +Now that you have the required software installed, it’s to time learn more about +declaring and using reproducible inveronments. + +The ideal workflow when using `{rix}` is to create a new, separate environment +at the start of a project. Let's say that you wish to analyse some data set, and +need `{dplyr}` and `{ggplot2}`. Let's also suppose that you use VS Code as your +IDE (there will be more discussion on editors in the vignette +`vignette("5-interactive_use")` but for now, let’s assume that you use VS Code). +With the `rix::rix()` function, you can easily generate the right `default.nix` +file. You need to provide the following inputs to `rix()`: + +- `r_ver`: the version of R required. Use "latest" for the latest version; +- `r_pkgs`: the required R packages. For example "dplyr" (more on this in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")`); +- `system_pkgs`: the required system packages, if needed. For example "quarto", or a Python interpreter (more on this in the vignette `vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`); +- `git_pkgs`: list of git packages to add (more on this in the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")`); +- `ide`: the integrated development editor to use (more on this in the vignette `vignette("5-interactive_use")`) +- `path`: the path where to save the `default.nix` file. +- `overwrite`: whether to overwrite the `default.nix` file or not. +- `print`: whether to print the `default.nix` file to the console or not. + +Run the following command to generate the right `default.nix` file: + + +```{r} +path_default_nix <- tempdir() + +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "code", + project_path = path_default_nix, + overwrite = TRUE, + print = TRUE) +``` + +To start using this environment, open a terminal in the folder containing +`default.nix` and use the following Nix command: + +``` +nix-build +``` + +`nix-build` is a Nix command that builds an environment according to the +specifications found in a `default.nix` file. Once the environment is done +building, you should find a new file called `result` next to the `default.nix` +file. This file is a symlink to the software installed by Nix. `{rix}` also +provides a `nix_build()` function to build Nix environments from within an +interactive R session, but it is not always guaranteed to succeed, due to +differences in platforms. This is explained in more detail in the following +vignette `vignette("advanced-topic-running-r-or-shell-code-in-nix-from-r")`. In case of doubt, run `nix-build` from your +usual terminal application. + +To now use the environment, type in the same terminal as before: + +``` +nix-shell +``` + +This will activate the environment. If you have VS Code installed you can +start it from this environment and VS Code will use this specific R version +library of packages. We will explore this in greater detail in the vignette +`vignette("5-interactive_use")`. + + +## Running old projects with {rix} + +The example below shows how to create a `default.nix` with instructions to build +an environment with R version 4.2.1, the `{dplyr}` and `{janitor}` packages and +no specific IDE: + + +```{r} +path_default_nix <- tempdir() + +rix(r_ver = "4.2.1", + r_pkgs = c("dplyr", "janitor"), + system_pkgs = c("quarto"), + git_pkgs = NULL, + ide = "other", + project_path = path_default_nix, + overwrite = TRUE) + +``` + +The file looks like this: + + +```{r echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +The first line is quite important, as it shows which *revision* of `nixpkgs` is +being used for this environment. The *revision* is the commit hash of that +particular release of `nixpkgs`, here: `79b3d4bcae8`. This revision of `nixpkgs` +is the one that shipped version 4.2.1 of R, so the `{dplyr}` and `{janitor}` +packages that will get installed will be the versions available in that revision +as well. This means that R versions and package versions are always coupled when +using Nix. However, if you need a specific version of R, but also a specific +version of a package that is not available in that particular Nix revision, one +solution is to install that package from Github or fro the CRAN archives. Read +the vignette `vignette("4a-installing-r-packages-in-a-nix-environment")` to know +more about this. To know which versions of R are available, read the documention +of `available_r()`. + + +## Running programs from an environment + +You could create a bash script that you put in the path to make the process of +launching your editor from that environment more streamlined. For example, if your +project is called `housing`, you could create this script and execute it to +start your project: + +``` +!#/bin/bash +nix-shell /absolute/path/to/housing/default.nix --run code +``` + +This will execute VS Code in the environment for the `housing` project. If you +use `{targets}` you could execute the pipeline in the environment by running: + +``` +cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'" +``` + + +## Running single functions in a subshell + +It is also possible to run single functions in an isolated environment from an +active R session using `with_nix()` and get the output of that function loaded +into the current session. Refer to this vignette +`vignette("advanced-topic-running-r-or-shell-code-in-nix-from-r")` for +more details on how to achieve this. Concretely this means that you could be +running R version 4.3.2 (installed via Nix, or not), and execute a function on R +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 +from the rest of the system. Suppose that you have the program `sl` installed on +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. + diff --git a/vignettes/4a-installing-r-packages-in-a-nix-environment.Rmd b/vignettes/4a-installing-r-packages-in-a-nix-environment.Rmd new file mode 100644 index 00000000..f78821f0 --- /dev/null +++ b/vignettes/4a-installing-r-packages-in-a-nix-environment.Rmd @@ -0,0 +1,130 @@ +--- +title: "4a - Installing R packages in a Nix environment" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{4a-installing-r-packages-in-a-nix-environment} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +## Introduction + +You now know how to declare and build reproducible development environments using `{rix}` +and Nix. This vignette will explain how to install specific versions of CRAN packages +and how to install packages from GitHub. + + +## Installing old packages archived on CRAN + +It is possible to install an arbitrary version of a package that has been +archived on CRAN: + + +```{r} +path_default_nix <- tempdir() + +rix(r_ver = "4.2.1", + 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) +``` + +```{r echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +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 +packages that have been archived, but otherwise, this feature should ideally be +used sparingly. If you want to reconstruct an environment as it was around 2019, +use the version of R that was current at that time. This will ensure that every +package that gets installed is at a version compatible with that version of R, +which might not be the case if you need to install a very old version of one +particular package. + + +## Installing packages from Github + +It is also possible to install packages from Github: + + +```{r} +rix(r_ver = "4.2.1", + 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) + +``` + +```{r echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +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 +is also installed, from the main branch at commit `d617172447d`. + + +## A complete example + +This example shows how to install packages from CRAN, from the CRAN archives and +from GitHub: + + +```{r} +rix(r_ver = "4.2.1", + 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) + +``` + +```{r echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +The next vignette, +`vignette("4b-installing-system-tools-and-texlive-packages-in-a-nix-environment")`, +explains how you can install tools such as text editors, git, Quarto, TexLive +packages, and any other tool available through `nixpkgs` for your development +environments. + diff --git a/vignettes/4b-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd b/vignettes/4b-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd new file mode 100644 index 00000000..e9a5c7e1 --- /dev/null +++ b/vignettes/4b-installing-system-tools-and-texlive-packages-in-a-nix-environment.Rmd @@ -0,0 +1,113 @@ +--- +title: "4b - Installing system tools and TexLive packages in a Nix environment" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{4b-installing-system-tools-and-texlive-packages-in-a-nix-environment} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +## Introduction + +More than 80'000 pieces of software are available through the Nix package +managers. Nix’s repository of packages is called `nixpkgs` and it includes the +entirety of CRAN and Bioconductor. `nixpkgs` is actually "just" a Github +repository containing thousands upon thousands of Nix expressions. When +installing a package, these expressions get evaluated, and the package in +question gets installed. What installed means can vary: sometimes the package +gets built from source, sometimes a pre-compiled binary package for your +operating system gets downloaded and made available. + +For example, +[here](https://github.com/NixOS/nixpkgs/blob/dce218f4f35440622d2056f93ddc335351763bb4/pkgs/development/libraries/quarto/default.nix) +is the Nix expression that downloads and installs [Quarto](https://quarto.org/). +This is an example of an expression that downloads the pre-compiled Quarto +binary from Quarto’s own Github repository, and then installs it. The +installation process in this case is essentially making sure that Quarto is able +to find its dependencies, which also get installed from Nix, and some R and +Python packages to make Quarto work well with both languages also get installed. + +It is possible to use `rix()` to add tools to an environment and this vignette +explains how. + + +## Adding tools to an environment + +The call below generates a `default.nix` that defines an environment with the 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} +path_default_nix <- tempdir() + +rix(r_ver = "latest", + r_pkgs = c("quarto"), + system_pkgs = c("quarto", "git"), + git_pkgs = NULL, + ide = "other", + project_path = path_default_nix, + overwrite = TRUE) +``` + +```{r echo = F} +cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") +``` + +You can look for all the available software +[here](https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=). +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 requires +a TexLive distribution to be installed. You can use `rix()` to install 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} +path_default_nix <- tempdir() + +rix(r_ver = "latest", + r_pkgs = c("quarto"), + system_pkgs = "quarto", + tex_pkgs = c("amsmath"), + ide = "other", + project_path = path_default_nix, + overwrite = TRUE, + print = TRUE) + +``` + +This will automically add the *small* TexLive distribution available through `nixpkgs` +with the `amsmath` LaTex package. To know more about setting up environments for +literate programming, refer to the vignette +`vignette("advanced-topic-building-an-environment-for-literate-programming")`. + + +## Installing IDEs + +Environments built with Nix are not completely cut off from the rest of your +system, and as such, you should be able to use your usual IDE to interact with +Nix environments. The only exception is RStudio. Everything will be explained in +greater detail in the vignette `vignette("5-interactive_use")`. + diff --git a/vignettes/5-interactive-use.Rmd b/vignettes/5-interactive-use.Rmd new file mode 100644 index 00000000..f3c19066 --- /dev/null +++ b/vignettes/5-interactive-use.Rmd @@ -0,0 +1,182 @@ +--- +title: "5 - Interactive use" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{5-interactive-use} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + +## Introduction + +This vignette describes interactive use of environments built with `{rix}` using +a GUI editor like RStudio. We will discuss three scenarios: one in which you +already have R and RStudio installed on your operating system using the usual +installation method for your operating system, another in which you used Nix +to install R and RStudio, and finally the last scenario assumes you use another +IDE than RStudio, for example VS Code, Emacs, Vim... + +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("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 +start using `{rix}` to define reproducible environments for your new projects +starting today. These environments will get built using the Nix package manager +and will not only include the required R packages for your project but also a +specific version of R, and any required system-level dependency as well. If you +are used to using RStudio, then you also need to install RStudio using Nix in +these project-specific environments. This is because RStudio re-defines many +environment variables and as such, a version of RStudio installed using the +usual installer for your operating system will not be able "to see" an R +interpreter installed with Nix. As stated in the macOS-specific vignette +`vignette("2b-setting-up-and-using-rix-on-macos")`, RStudio is not available on +macOS through `nixpkgs`. The following instructions are thus only applicable to +Linux and Windows. If you’re on macOS, read the macOS-specific vignette if +that’s not done already, and then come back here and skip to the "scenario 3" of +this vignette. + +To run a project-specific version of RStudio and R, you will first need to +create a `default.nix` file and build the environment defined therein using Nix. +Once this is done, you then need to activate the environment before running this +project-specific version of RStudio. Suppose for example that you generated a +`default.nix` file for a project called "kmeans", and suppose that this project +is in the following path: `~/Documents/kmeans` (on Windows it would be something +like `C:\Users\Billy\Documents\kmeans`). For example, here is how you could use +`{rix}` to generate the `default.nix` for this environment: + + +```{r 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 eval = FALSE} +library(rix) + +path_to_project <- ~/Documents/kmeans + +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "rstudio", + project_path = path_to_project, + overwrite = TRUE, + print = TRUE) +``` + +Navigate to that folder using your terminal, and then run `nix-shell`. You will +then be *dropped into* a Nix shell. From there 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}`. You can then work on +it as usual. + +You can also define a shortcut to a project that will take care of activating +the environment and launching RStudio. This way, you don't need to start a +terminal in that folder and drop into the Nix environment each time you want to +work on this project. For example, you could define a bash alias like this: + + alias kmeans='nix-shell ~/Documents/kmeans/default.nix --run rstudio + +which would then execute RStudio in the right project by simply typing `kmeans` +in a terminal. It's also possible to create an executable script that you can +save in your PATH: + + #!/usr/bin/env nix-shell + #!nix-shell /home/Billy/Document/kmeans/default.nix -i bash + rstudio + +Name this script something like `kmeans_project`, make it executable (using +`chmod +x kmeans_project`), and now you can run RStudio within this environment +from anywhere. + + +## Scenario 2: you don't have any regular R and RStudio installation yet + +If you don't have R installed you cannot use the `{rix}` package to generate new +expressions. In this case you might consider installing Nix first, and then run +the following command inside your terminal to get dropped into a temporary Nix +shell, which you can then use to generate new `default.nix` files: + + nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" + +Running the command above will download R and `{rix}` and then start an R +session inside your terminal. You can now run something like this: + + rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "rstudio", + # change to a project's path or leave it if you're in the right folder already + project_path = ".", + overwrite = TRUE) + +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 +could install `{rix}` in that environment to generate new `default.nix` files. + + +## Scenario 3: you use some IDE other than RStudio + +VS Code and Emacs have been tested and unlike RStudio, you can use a version of +VS Code or Emacs installed through the usual means on your system with +development environments built with Nix. But there's nothing stopping you from +installing a project-specific version of VS Code or Emacs as well if you wish. +Configuration and settings should be accessible across every version from every +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: + +``` +rix(r_ver = "latest", + r_pkgs = c("dplyr", "ggplot2"), + system_pkgs = NULL, + git_pkgs = NULL, + ide = "code", + project_path = ".", + overwrite = TRUE) +``` + +Notice the `ide = "code"` argument. This will not install VS Code from Nix, but +will install the `{languageserver}` package that is needed for using R with VS +Code. If you want to also install a project-specific version of VS Code, then +use `system_pkgs = "vscode"` or `system_pkgs = "vscodium"` if you prefer VS +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. + + +## 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/building-an-environment-for-literate-programming.Rmd b/vignettes/advanced-topic-building-an-environment-for-literate-programming.Rmd similarity index 97% rename from vignettes/building-an-environment-for-literate-programming.Rmd rename to vignettes/advanced-topic-building-an-environment-for-literate-programming.Rmd index 06e307c6..7b89c618 100644 --- a/vignettes/building-an-environment-for-literate-programming.Rmd +++ b/vignettes/advanced-topic-building-an-environment-for-literate-programming.Rmd @@ -1,8 +1,8 @@ --- -title: "Building an environment for literate programming" +title: "Advanced topic: Building an environment for literate programming" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{building-an-environment-for-literate-programming} + %\VignetteIndexEntry{advanced-topic-building-an-environment-for-literate-programming} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -69,10 +69,11 @@ with this small version, you can click [here](https://search.nixos.org/packages?channel=unstable&show=texlive.combined.scheme-small&from=0&size=50&sort=relevance&type=packages&query=scheme-small). We start by adding the `amsmath` package then build the environment using: - -```{r eval = F} -nix_build() ``` +nix-build +``` + +from a terminal, or `nix_build()` from an interactive R session. Then, drop into the Nix shell with `nix-shell`, and run `quarto add quarto-journals/jss`. This will install the template linked above. Then, in the @@ -272,7 +273,7 @@ document. This is in contrast to before where we used `quarto add quarto-journals/jss` to install the template. Doing this interactively makes our project not reproducible because if we compile our Quarto doc today, we would be using the template as it is today, but if we compile the document in 6 months, -then we would be using the template as it would be in 6 months (I should say +then we would be using the template as it would be in 6 months (we should say that it is possible to install specific releases of Quarto templates using following notation: `quarto add quarto-journals/jss@v0.9.2` so this problem can be mitigated). @@ -360,6 +361,5 @@ This vignette showed two approaches, both have their merits: the first approach that is more interactive is useful while writing the document. You get access to a shell and can work on the document and compile it quickly. The second approach is more useful once the document is ready and you want to have a way of quickly -rebuilding it for reproducibility purposes. This approach should also be quite -useful in a CI/CD environment. +rebuilding it for reproducibility purposes. diff --git a/vignettes/handling-packages-with-remote-dependencies.Rmd b/vignettes/advanced-topic-handling-packages-with-remote-dependencies.Rmd similarity index 79% rename from vignettes/handling-packages-with-remote-dependencies.Rmd rename to vignettes/advanced-topic-handling-packages-with-remote-dependencies.Rmd index f4d265c8..dc4cd5fa 100644 --- a/vignettes/handling-packages-with-remote-dependencies.Rmd +++ b/vignettes/advanced-topic-handling-packages-with-remote-dependencies.Rmd @@ -1,8 +1,8 @@ --- -title: "Handling packages with remote dependencies" +title: "Advanced topic: Handling packages with remote dependencies" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{handling-packages-with-remote-dependencies} + %\VignetteIndexEntry{advanced-topic-handling-packages-with-remote-dependencies} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -22,22 +22,23 @@ library(rix) ## Introduction -Packages on CRAN must have their dependencies on either CRAN or Bioconductor, -but not on Github. However, there are many packages available on Github that -never get published on CRAN, and some of these packages may even depend on other -packages that are also only available on Github. `{rix}` makes it possible to -install packages from Github, but in case one of the package's dependencies has -also only been released on Github, building the Nix environment will fail. This -is because Nix will be looking for these packages on `nixpkgs`, but only -packages released on CRAN and Bioconductor are available through `nixpkgs`. This -vignette explains how to install such a packages with dependencies on Github. +Packages published on CRAN must have their dependencies on either CRAN or +Bioconductor, but not on GitHub. However, there are many packages available on +GitHub that never get published on CRAN, and some of these packages may even +depend on other packages that are also only available on GitHub. `{rix}` makes +it possible to install packages from GitHub, but in case one of the package's +dependencies has also only been released on GitHub, building the Nix environment +will fail. This is because Nix will be looking for these packages on `nixpkgs`, +but only packages released on CRAN and Bioconductor are available through +`nixpkgs`. This vignette explains how to install such a packages that have +dependencies only available on GitHub. ## The {lookup} package As an example we are going to use the [{lookup}](https://github.com/jimhester/lookup) package which has only been -released on Github. [Here is the +released on GitHub. [Here is the repository](https://github.com/jimhester/lookup). This package comes with the `lookup()` function which makes it possible to check the source code of any function from a loaded package, even if the source of that function is in C or @@ -73,7 +74,7 @@ error: attribute 'highlite' missing ## Building remote dependencies `{highlite}` is a dependency of [{lookup}](https://github.com/jimhester/lookup) -that is only available on CRAN. This can be checked by looking at the +that is only available on GitHub. This can be checked by looking at the `DESCRIPTION` file of [{lookup}](https://github.com/jimhester/lookup): ``` @@ -83,11 +84,11 @@ Remotes: hadley/memoise ``` -We see that there are actually three packages that come from Github: but -`{gh}` and `{memoise}` have in the meantime been released on CRAN, which means -that they are also available through `nixpkgs`. We have to deal with `{highlite}` -however. Doing so is fairly easy: first, create a new expression using `{rix}` -to install `{highlite}`: +We see that there are actually three packages that come from GitHub: but `{gh}` +and `{memoise}` have in the meantime been released on CRAN, which means that +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}`: ``` rix(r_ver = "latest", @@ -184,8 +185,8 @@ propagatedBuildInputs = builtins.attrValues { Building the expression now succeeds. -We know that this is quite tedious, but at the moment there are no plans to -make `{rix}` handle remote dependencies automatically. This is for mainly three +We know that this is quite tedious, but at the moment there are no plans to make +`{rix}` handle remote dependencies automatically. This is for mainly three reasons: - packages with remote dependencies are rare, and never on CRAN on Bioconductor; diff --git a/vignettes/reproducible-analytical-pipelines-with-nix.Rmd b/vignettes/advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd similarity index 50% rename from vignettes/reproducible-analytical-pipelines-with-nix.Rmd rename to vignettes/advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd index 70cf4383..75ab3b71 100644 --- a/vignettes/reproducible-analytical-pipelines-with-nix.Rmd +++ b/vignettes/advanced-topic-reproducible-analytical-pipelines-with-nix.Rmd @@ -1,8 +1,8 @@ --- -title: "Reproducible Analytical Pipelines with Nix" +title: "Advanced topic: Reproducible Analytical Pipelines with Nix" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{reproducible-analytical-pipelines-with-nix} + %\VignetteIndexEntry{advanced-topic-reproducible-analytical-pipelines-with-nix} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -30,9 +30,9 @@ packages. ## An example of a reproducible analytical pipeline using Nix -Suppose that I used `{targets}` to build a pipeline for a project and that I did -so using a tailor-made Nix environment. Here is the call to `rix()` that I used -to build that environment: +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} @@ -60,15 +60,15 @@ cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") 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 I developing specifically for this project. -Because it is on Github, it gets installed using the `buildRPackage` function -from Nix. I can use this environment to work on my project, or to launch my -`{targets}` pipeline. [This Github +packages, which is a package that is hosted on GitHub only with some data and +useful functions for the project. Because it is on Github, it gets installed +using the `buildRPackage` function from Nix. You can use this environment to +work on you project, or to launch a `{targets}` pipeline. [This Github repository](https://github.com/b-rodrigues/nix_targets_pipeline/tree/master) contains the finalized project. -If you use `{targets}` you could execute the pipeline in the environment by -running in a terminal: +On your local machine, you could execute the pipeline in the environment by +running this in a terminal: ``` cd /absolute/path/to/housing/ && nix-shell default.nix --run "Rscript -e 'targets::tar_make()'" @@ -77,22 +77,29 @@ 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: -``` -... -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 ]; - shellHook = '' Rscript -e "targets::tar_make()" ''; -} + +```{r eval = FALSE} +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", + shell_hook = "Rscript -e 'targets::tar_make()'", + project_path = path_default_nix, + overwrite = TRUE) ``` Now, each time you drop into the Nix shell for that project using `nix-shell`, -the pipeline gets automatically executed. +the pipeline gets automatically executed. `{rix}` also features a function +called `tar_nix_ga()` that adds a GitHub Actions workflow file to make the +pipeline run automatically on GitHub Actions. The GitHub repository linked above +has such a file, so each time changes get pushed, the pipeline runs on Github +Actions and the results are automatically pushed to a branch called +`targets-runs`. See the workflow file +[here](https://github.com/b-rodrigues/nix_targets_pipeline/blob/master/.github/workflows/run-pipeline.yaml). +This feature is very heavily inspired and adapted from the +`targets::github_actions()` function. diff --git a/vignettes/running-r-or-shell-code-in-nix-from-r.Rmd b/vignettes/advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd similarity index 98% rename from vignettes/running-r-or-shell-code-in-nix-from-r.Rmd rename to vignettes/advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd index e34c7ce8..9b61e2a9 100644 --- a/vignettes/running-r-or-shell-code-in-nix-from-r.Rmd +++ b/vignettes/advanced-topic-running-r-or-shell-code-in-nix-from-r.Rmd @@ -1,8 +1,8 @@ --- -title: "Running R or shell code in Nix from R" +title: "Advanced topic: Running R or Shell Code in Nix from R" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{running-r-or-shell-code-in-nix-from-r} + %\VignetteIndexEntry{advanced-topic-running-r-or-shell-code-in-nix-from-r} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -18,7 +18,7 @@ knitr::opts_chunk$set( library(rix) ``` - + ## **Testing code in evolving software dependency environments with confidence** diff --git a/vignettes/building-reproducible-development-environments-with-rix.Rmd b/vignettes/building-reproducible-development-environments-with-rix.Rmd deleted file mode 100644 index 1951696a..00000000 --- a/vignettes/building-reproducible-development-environments-with-rix.Rmd +++ /dev/null @@ -1,297 +0,0 @@ ---- -title: "Building reproducible development environments with rix" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{building-reproducible-development-environments-with-rix} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -``` - -```{r setup} -library(rix) -``` - - - -## Introduction and installation - -The goal of `{rix}` is to provide an easy way to generate `default.nix` files. -These files are used by the Nix package manager to build an environment -according to the instructions defined in it. Users can specify which version of -R, R packages, other needed software, IDE etc should be available within that -environment. Writing such files can be daunting for newcomers, and so `{rix}` -provides a function called `rix()`, which takes care of the bulk of the work - -`{rix}` does not require Nix to be installed to generate `default.nix` files, so -you could generate the file on one machine, and then build and use the -environment on another machine that has Nix installed on it (or on a CI/CD -service like Github Actions for example). If you wish to fully take advantage of -Nix, I suggest you use [Determinate System's -installer](https://zero-to-nix.com/start/install). Nix can be installed on -Linux, macOS and Windows (but on Windows WSL2 must be enabled). - -On Linux, once Nix is instaled, all the software that will be installed will be -saved to the `/nix` directory on the root partition. Complete development -environments built with Nix can take up much space, so if the available space on -your root parttion is limited, I advise you to mount the `/nix` folder on -another partition with more space (for example, a secondary hard drive). For -this, edit `/etc/fstab` and add the following line at the end: - -``` -/home/path_to/nix /nix none bind 0 0 -``` - -This will map `/nix` to `/home/path_to/nix` which can be on a larger partition. -If you have enough space on your root partition, you can ignore the above -instructions. - - -## Nix environments - -An environment built by Nix is not totally isolated from the rest of the system. -Suppose that you the program `sl` installed on 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. This can -be useful when working interactively with a Nix environment, because you can use -your usual IDE to work with it. The only exception is RStudio: RStudio looks for -R in predefined paths and cannot "see" the R provided by a Nix environment, it -will instead use the version installed on your machine. This means that if you -use RStudio to work interactively with R, you will need to install RStudio -inside that environment. `rix::rix()` can generate a `default.nix` file that -does that. - - -## Day-to-day use of {rix} - -The ideal workflow when using `{rix}` is to create a new, separate environment -at the start of a project. Let's say that you wish to analyse some data set, and -need `{dplyr}` and `{ggplot2}`. Let's also suppose that you use RStudio as your -IDE. With the `rix::rix()` function, you can easily generate the right -`default.nix` file. You need to provide the following inputs to `rix()`: - -- `r_ver`: the version of R required. Use "latest" for the latest version; -- `r_pkgs`: the required R packages. For example "dplyr"; -- `system_pkgs`: the required system packages, if needed. For example "quarto", or a Python interpreter; -- `git_pkgs`: list of git packages to add. See the example below; -- `ide`: the integrated development editor to use. For example "rstudio" if you want to use RStudio. Refer to the "Interactive work with {rix}" for more details; -- `path`: the path where to save the `default.nix` file. -- `overwrite`: whether to overwrite the `default.nix` file or not. -- `print`: whether to print the `default.nix` file to the console or not. - -In such a situation, you could create an environment with the following call to `rix()`: - - -```{r} -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) -``` - -To start using this environment, open a console in the folder containing -`default.nix` and use the following Nix command: - -``` -nix-build -``` - -`nix-build` is a Nix command that builds an environment according to the -specifications found in a `default.nix` file. Once the environment is done -building, you should find a new file called `result` next to the `default.nix` -file. This file is a symlink to the software installed by Nix. To now use the -environment, type: - -``` -nix-shell -``` - -You can now start the RStudio provided by that environment by typing `rstudio`. -This will start a version of RStudio specific to this environment. If you -already had RStudio installed by using your operating system's installer, that -version of RStudio will not be able to interact with Nix environments. This is -because RStudio looks for R in certain specific paths that don't include any Nix -environments. This is not the case with other editors like Visual Studio Code or -Emacs. If you use Visual Studio Code, you can use the following call to `rix()`: - - -```{r} -path_default_nix <- tempdir() - -rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "code", - project_path = path_default_nix, - overwrite = TRUE) -``` - -(note the value provided to the `ide` argument). - -This generates the following `default.nix` file: - - -```{r echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -As you can see, specifying `ide = "code"` adds the `{languageserver}` package to -the list of packages that must be installed for this environment. This is -because Visual Studio Code requires this package to interact with R. This will -not install a Nix environment-specific version of Visual Studio Code. Now, -instead of typing `rstudio` in the Nix shell of your environment, type `code` -and this will start the Visual Studio Code you usually use. - -If you use another editor, like Emacs, then use `ide = "other"`, and start that -editor inside an activated Nix environment. - -For more details on interactive use, read the "Interactive use" vignette. - - -## Running old projects with {rix} - -The example below shows how to create a `default.nix` with instructions to build -an environment with R version 4.2.1, the `{dplyr}` and `{janitor}` packages and -no specific IDE: - - -```{r} -path_default_nix <- tempdir() - -rix(r_ver = "4.2.1", - r_pkgs = c("dplyr", "janitor"), - system_pkgs = c("quarto"), - git_pkgs = NULL, - ide = "other", - project_path = path_default_nix, - overwrite = TRUE) - -``` - -The file looks like this: - - -```{r echo = F} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -The first line is quite important, as it shows which *revision* of `nixpkgs` is -being used for this environment. The *revision* is the commit hash of that -particular release of `nixpkgs`, here: `79b3d4bcae8`. This revision of `nixpkgs` -is the one that shipped version 4.2.1 of R, so the `{dplyr}` and `{janitor}` -packages that will get installed will be the versions available in that revision -as well. This means that R versions and package versions are always coupled when -using Nix. However, if you need a specific version of R, but also a specific -version of a package that is not available in that particular Nix revision, one -solution is to install that package from Github. - - -## Installing old packages archived on CRAN - -It is also possible to install an arbitrary version of a package that has -been archived on CRAN: - - -```{r} -rix(r_ver = "4.2.1", - 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) -``` - -```{r} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -This feature should ideally be used sparingly. If you want to reconstruct an -environment as it was around 2019, use the version of R that was current at the -time. This will ensure that every package that gets installed is at a version -compatible with that version of R, which might not be the case if you need to -install a very old version of one particular package. - - -## Installing packages from Github - -It is also possible to install packages from Github: - - -```{r} -rix(r_ver = "4.2.1", - r_pkgs = c("dplyr", "janitor"), - system_pkgs = c("quarto"), - 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) - -``` - -```{r} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -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 -is also installed, from the main branch at commit `d617172447d`. - - -## A complete example - -This example shows how all features of `{rix}` can work together: - - -```{r} -rix(r_ver = "4.2.1", - r_pkgs = c("dplyr", "janitor", "AER@1.2-8"), - system_pkgs = c("quarto"), - 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 = "rstudio", - project_path = path_default_nix, - overwrite = TRUE) - -``` - -```{r} -cat(readLines(paste0(path_default_nix, "/default.nix")), sep = "\n") -``` - -To learn more about using `{rix}` on a daily basis, read the [Interactive -use](https://b-rodrigues.github.io/rix/articles/interactive-use.html) vignette. - diff --git a/vignettes/save-the-nix-package-versions-data.Rmd b/vignettes/developers-vignette-save-the-nix-package-versions-data.Rmd similarity index 72% rename from vignettes/save-the-nix-package-versions-data.Rmd rename to vignettes/developers-vignette-save-the-nix-package-versions-data.Rmd index 3e252666..71c59f1e 100644 --- a/vignettes/save-the-nix-package-versions-data.Rmd +++ b/vignettes/developers-vignette-save-the-nix-package-versions-data.Rmd @@ -1,8 +1,8 @@ --- -title: "Save the Nix Package Versions data" +title: "Developers Vignette: Save the Nix Package Versions data" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{save-the-nix-package-versions-data} + %\VignetteIndexEntry{developers-vignette-save-the-nix-package-versions-data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -18,7 +18,9 @@ knitr::opts_chunk$set( library(rix) ``` - + + +This vignette is only needed for the developers of `{rix}`. To install old versions of R, specific Nix revisions must be used. This tool [Nix Package Versions](https://lazamar.co.uk/nix-versions/) provides a simple diff --git a/vignettes/interactive-use.Rmd b/vignettes/interactive-use.Rmd deleted file mode 100644 index 80fc2b7b..00000000 --- a/vignettes/interactive-use.Rmd +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: "Interactive use" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{interactive-use} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -``` - -```{r setup} -library(rix) -``` - - - -## Introduction - -This vignette describes interactive use of environments built with `{rix}` using -a GUI editor like RStudio. I will discuss two scenarios: one in which you -already have R and RStudio installed on your operating system using the usual -installation method for your operating system, and another in which you used Nix -to install R and RStudio (or any other IDE). - - -## Scenario 0: you installed nix and want to build from an expression using {rix} - -We have a little helper `rix::nix_build()` which calls `nix-build` from R. All -you need is nix installed, and the curl command line utility or {curl}, its -interface from R. Here is an example to get the nix expression that can use -to build the "latest" R version available from nix and the development version -of {rix} from GitHub. - - -```{sh eval = FALSE} -curl -sl -o default.nix https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix -``` - -Then open an R session from terminal located in your project root folder. - - -```{r eval = FALSE} -nix_build(project_path = ".", exec_mode = "non-blocking") -``` - -This will build your project and stream messages and errors back in your -R console. - - -## Scenario 1: you installed R and RStudio as usual - -Let's suppose that you are already running R and RStudio and that you wish to -start using `{rix}` to define reproducible environments for your new projects -starting today. These environments will get built using the Nix package manager -and will not only include the required R packages for your project but also a -specific version of R, and any required system-level dependency as well. If you -are used to using RStudio, then you also need to install RStudio using Nix in -these project-specific environments. To run a project-specific version of -RStudio and R, you will first need to create a `default.nix` file and build the -environment defined therein using Nix. Once this is done, you then need to -activate the environment before running this project-specific version of -RStudio. Suppose for example that you generated a `default.nix` file for a -project called "kmeans", and suppose that this project is in the following path: -`~/Documents/kmeans` (on Windows it would be something like -`C:\Users\Billy\Documents\kmeans`). Navigate to that folder using your terminal, -and then run `nix-shell`. You will then be *dropped into* a Nix shell. From -there you can type `rstudio` to run this project specific version of RStudio -with all the packages. You can then work on it as usual. - -You can also define a shortcut to a project that will take care of activating -the environment and launching rstudio. For example, you could define a bash -alias like this: - - alias kmeans='nix-shell ~/Documents/kmeans/default.nix --run rstudio - -which would then execute RStudio in the right project by simply typing `kmeans` -in a terminal. It's also possible to create an executable script that you can -save in your PATH: - - #!/usr/bin/env nix-shell - #!nix-shell /home/Billy/Document/kmeans/default.nix -i bash - rstudio - -Name this script something like `kmeans_project`, make it executable (using -`chmod +x kmeans_project`), and now you can run RStudio within this environment -from anywhere. - - -## Scenario 2: you install R and RStudio using Nix - -If you don't have R installed you cannot use the `{rix}` package to generate new -expressions. In this case you might consider installing Nix first, and then -running the following command inside your terminal to get dropped into a -temporary Nix shell, which you can then use to generate new `default.nix` files: - - nix-shell --expr "$(curl -sl https://raw.githubusercontent.com/b-rodrigues/rix/master/inst/extdata/default.nix)" - -Running the command above will download R and `{rix}` and then start an R -session inside your terminal. You can now run something like this: - - rix(r_ver = "latest", - r_pkgs = c("dplyr", "ggplot2"), - system_pkgs = NULL, - git_pkgs = NULL, - ide = "rstudio", - project_path = ".", # change to a project's path - overwrite = TRUE) - -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`. - - -## Other IDEs - -Visual Studio Code and Emacs have been tested and unlike RStudio, you can use -the version of either VS Code or Emacs that you already have installed on your -system. But there's nothing stopping you from installing a project-specific -version of VS Code or Emacs as well. Configuration and settings should be -accessible across every version from every environment, since these are globally -defined at the level of your system. -