From f80ed72a107fca0465d23405942f741fcd667e9a Mon Sep 17 00:00:00 2001 From: Bruno Rodrigues Date: Sat, 15 Jul 2023 16:19:24 +0200 Subject: [PATCH] basic functionality is done --- NAMESPACE | 3 + R/find_rev.R | 106 ++++++++++++++++++++++++ dev/0-dev_history.Rmd | 6 ++ dev/build_envs.Rmd | 147 +++++++++++++++++++++++++++++++++ dev/config_fusen.yaml | 13 +++ dev/flat_minimal_package.Rmd | 45 ---------- man/available_r.Rd | 17 ++++ man/find_rev.Rd | 20 +++++ man/rix.Rd | 47 +++++++++++ tests/testthat/test-find_rev.R | 6 ++ vignettes/dev-build_envs.Rmd | 40 +++++++++ 11 files changed, 405 insertions(+), 45 deletions(-) create mode 100644 R/find_rev.R create mode 100644 dev/build_envs.Rmd delete mode 100644 dev/flat_minimal_package.Rmd create mode 100644 man/available_r.Rd create mode 100644 man/find_rev.Rd create mode 100644 man/rix.Rd create mode 100644 tests/testthat/test-find_rev.R create mode 100644 vignettes/dev-build_envs.Rmd diff --git a/NAMESPACE b/NAMESPACE index 64cac2aa..5da41b13 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,8 @@ # Generated by roxygen2: do not edit by hand export("%>%") +export(available_r) +export(find_rev) export(my_fun) +export(rix) importFrom(magrittr,"%>%") diff --git a/R/find_rev.R b/R/find_rev.R new file mode 100644 index 00000000..f55f26d4 --- /dev/null +++ b/R/find_rev.R @@ -0,0 +1,106 @@ +# WARNING - Generated by {fusen} from dev/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" +#' @return A character. The Nix revision to use +#' @export +#' +#' @examples +#' find_rev("4.2.0") +find_rev <- function(r_version){ + + temp <- new.env(parent = emptyenv()) + + data(list = "r_nix_revs", + package = "rix", + envir = temp) + + get("r_nix_revs", envir = temp) + + output <- r_nix_revs$revision[r_nix_revs$version == r_version] + + stopifnot("Error: the provided R version is likely wrong. Please check that you provided a correct R version. You can list available versions using `available_r()`" = !identical(character(0), output)) + + output +} + + +#' available_r List available R versions +#' @return A character vector containing the available R versrions. +#' @export +#' +#' @examples +#' available_r() +available_r <- function(){ + + temp <- new.env(parent = emptyenv()) + + data(list = "r_nix_revs", + package = "rix", + envir = temp) + + get("r_nix_revs", envir = temp) + + r_nix_revs$version + +} + + +#' rix Build a reproducible development environment definition +#' @return Nothing, this function only has the side-effect of writing a file +#' called "default.nix" in the working directory. This file contains the +#' instructions to build a reproducible environment using the Nix package +#' manager. +#' @param r_ver Character. The required R version. Leave this argument empty if +#' you want to use the latest R version available. You can check which R +#' versions are available using `available_r` +#' @param pkgs Vector of characters. List the required packages for your +#' analysis here. +#' @param rstudio Logical, defaults to FALSE. If TRUE, RStudio gets installed in +#' this environment to enable interactive work. +#' @param path Character. Where to write `default.nix`. +#' @details This function will write a `default.nix` in the chosen path. Using +#' the Nix package manager, it is then possible to build a reproducible +#' development environment using the `nix-build` command in the path. This +#' environment will contain the chosen version of R and packages, and will not +#' interfere with any other installed version (via Nix or not) on your +#' machine. Every dependency, including both R package dependencies but also +#' system dependencies like compilers will get installed as well in that +#' environment. If you use RStudio for interactive work, then set the +#' `rstudio` parameter to `TRUE`. If you use another IDE (for example Emacs or +#' Visual Studio Code), you do not need to add it to the `default.nix` file, +#' you can simply use the version that is installed on your computer. To use +#' Visual Studio Code however, you need to install the `{languageserver}` +#' package, so don't forget to add it to the list of packages. Once you built +#' the environment using `nix-build`, you can drop into an interactive session +#' using `nix-shell`. See the "How-to Nix" vignette for more details. +#' @export +rix <- function(r_ver, pkgs, rstudio = FALSE, path = "."){ + nixTemplate <- " + { pkgs ? import (fetchTarball 'https://github.com/NixOS/nixpkgs/archive/RE_VERSION.tar.gz') {} }: + + with pkgs; + + let + my-r = rWrapper.override { + packages = with rPackages; [PACKAGE_LIST]; + }; +USE_RSTUDIO my-rstudio = rstudioWrapper.override { +USE_RSTUDIO packages = with rPackages; [PACKAGE_LIST]; +USE_RSTUDIO}; + in + mkShell { + buildInputs = [ + my-r + USE_RSTUDIO my-rstudio + ]; + }" + + nixFile <- gsub('RE_VERSION', find_rev(r_ver) , nixTemplate) + packages <- paste(pkgs, collapse = ' ') + nixFile <- gsub('PACKAGE_LIST', packages, nixFile) + nixFile <- gsub('USE_RSTUDIO', ifelse(rstudio, '', '#'), nixFile) + + writeLines(nixFile, normalizePath(paste0(path, "/default.nix"))) +} + diff --git a/dev/0-dev_history.Rmd b/dev/0-dev_history.Rmd index 86dc6ae4..12616f2f 100755 --- a/dev/0-dev_history.Rmd +++ b/dev/0-dev_history.Rmd @@ -64,6 +64,12 @@ usethis::use_git() **From now, you will need to "inflate" your package at least once to be able to use the following commands. Let's go to your flat template, and come back here later if/when needed.** +```{r} +fusen::inflate(flat_file = "dev/build_envs.Rmd", + vignette_name = "dev-build_envs", + overwrite = TRUE) +``` + ```{r development-inflate, eval=FALSE} # Run but keep eval=FALSE to avoid infinite loop # Execute in the console directly diff --git a/dev/build_envs.Rmd b/dev/build_envs.Rmd new file mode 100644 index 00000000..fdea6db6 --- /dev/null +++ b/dev/build_envs.Rmd @@ -0,0 +1,147 @@ +--- +title: "RIX: functions" +output: html_document +editor_options: + chunk_output_type: console +--- + +```{r development, include=FALSE} +library(testthat) +``` + + + +```{r development-load} +# Load already included functions if relevant +pkgload::load_all(export_all = FALSE) +``` + +This function takes an R version as an input and returns the Nix revision that provides it: + +```{r function-find_rev} +#' find_rev Find the right Nix revision +#' @param r_version Character. R version to look for, for example, "4.2.0" +#' @return A character. The Nix revision to use +#' @export +#' +#' @examples +#' find_rev("4.2.0") +find_rev <- function(r_version){ + + temp <- new.env(parent = emptyenv()) + + data(list = "r_nix_revs", + package = "rix", + envir = temp) + + get("r_nix_revs", envir = temp) + + output <- r_nix_revs$revision[r_nix_revs$version == r_version] + + stopifnot("Error: the provided R version is likely wrong. Please check that you provided a correct R version. You can list available versions using `available_r()`" = !identical(character(0), output)) + + output +} + +``` + +```{r tests-find_rev} +testthat::expect_equal( + find_rev("4.2.2"), + "8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8" + ) +``` + +This function return available R versions: + +```{r function-available_r} +#' available_r List available R versions +#' @return A character vector containing the available R versrions. +#' @export +#' +#' @examples +#' available_r() +available_r <- function(){ + + temp <- new.env(parent = emptyenv()) + + data(list = "r_nix_revs", + package = "rix", + envir = temp) + + get("r_nix_revs", envir = temp) + + r_nix_revs$version + +} + +``` + +This next function returns a `default.nix` file that can be used to build a +reproducible environment. This function takes an R version as an input (the +correct Nix revision is found using `find_rev()`), a list of R packages, and +whether the user wants to work with RStudio or not in that environment. If +you use another IDE, you can leave the "rstudio" argument blank: + +```{r function-rix} +#' rix Build a reproducible development environment definition +#' @return Nothing, this function only has the side-effect of writing a file +#' called "default.nix" in the working directory. This file contains the +#' instructions to build a reproducible environment using the Nix package +#' manager. +#' @param r_ver Character. The required R version. Leave this argument empty if +#' you want to use the latest R version available. You can check which R +#' versions are available using `available_r` +#' @param pkgs Vector of characters. List the required packages for your +#' analysis here. +#' @param rstudio Logical, defaults to FALSE. If TRUE, RStudio gets installed in +#' this environment to enable interactive work. +#' @param path Character. Where to write `default.nix`. +#' @details This function will write a `default.nix` in the chosen path. Using +#' the Nix package manager, it is then possible to build a reproducible +#' development environment using the `nix-build` command in the path. This +#' environment will contain the chosen version of R and packages, and will not +#' interfere with any other installed version (via Nix or not) on your +#' machine. Every dependency, including both R package dependencies but also +#' system dependencies like compilers will get installed as well in that +#' environment. If you use RStudio for interactive work, then set the +#' `rstudio` parameter to `TRUE`. If you use another IDE (for example Emacs or +#' Visual Studio Code), you do not need to add it to the `default.nix` file, +#' you can simply use the version that is installed on your computer. To use +#' Visual Studio Code however, you need to install the `{languageserver}` +#' package, so don't forget to add it to the list of packages. Once you built +#' the environment using `nix-build`, you can drop into an interactive session +#' using `nix-shell`. See the "How-to Nix" vignette for more details. +#' @export +rix <- function(r_ver, pkgs, rstudio = FALSE, path = "."){ + nixTemplate <- " + { pkgs ? import (fetchTarball 'https://github.com/NixOS/nixpkgs/archive/RE_VERSION.tar.gz') {} }: + + with pkgs; + + let + my-r = rWrapper.override { + packages = with rPackages; [PACKAGE_LIST]; + }; +USE_RSTUDIO my-rstudio = rstudioWrapper.override { +USE_RSTUDIO packages = with rPackages; [PACKAGE_LIST]; +USE_RSTUDIO}; + in + mkShell { + buildInputs = [ + my-r + USE_RSTUDIO my-rstudio + ]; + }" + + nixFile <- gsub('RE_VERSION', find_rev(r_ver) , nixTemplate) + packages <- paste(pkgs, collapse = ' ') + nixFile <- gsub('PACKAGE_LIST', packages, nixFile) + nixFile <- gsub('USE_RSTUDIO', ifelse(rstudio, '', '#'), nixFile) + + writeLines(nixFile, normalizePath(paste0(path, "/default.nix"))) +} + +``` diff --git a/dev/config_fusen.yaml b/dev/config_fusen.yaml index d0346e7e..413db6da 100644 --- a/dev/config_fusen.yaml +++ b/dev/config_fusen.yaml @@ -1,3 +1,16 @@ +build_envs.Rmd: + path: dev/build_envs.Rmd + state: active + R: R/find_rev.R + tests: tests/testthat/test-find_rev.R + vignettes: vignettes/dev-build_envs.Rmd + inflate: + flat_file: dev/build_envs.Rmd + vignette_name: dev-build_envs + open_vignette: true + check: true + document: true + overwrite: 'yes' data_doc.Rmd: path: dev/data_doc.Rmd state: active diff --git a/dev/flat_minimal_package.Rmd b/dev/flat_minimal_package.Rmd deleted file mode 100644 index a578d2e2..00000000 --- a/dev/flat_minimal_package.Rmd +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: "flat_minimal_package.Rmd empty" -output: html_document -editor_options: - chunk_output_type: console ---- - -```{r development, include=FALSE} -library(testthat) -``` - - - -```{r development-load} -# Load already included functions if relevant -pkgload::load_all(export_all = FALSE) -``` - -# my_fun - -```{r function-my_fun} -#' my_fun Title -#' -#' @return 1 -#' @export -#' -#' @examples -my_fun <- function() { - 1 -} -``` - -```{r examples-my_fun} -my_fun() -``` - -```{r tests-my_fun} -test_that("my_fun works", { - -}) -``` - - diff --git a/man/available_r.Rd b/man/available_r.Rd new file mode 100644 index 00000000..b797d86b --- /dev/null +++ b/man/available_r.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/find_rev.R +\name{available_r} +\alias{available_r} +\title{available_r List available R versions} +\usage{ +available_r() +} +\value{ +A character vector containing the available R versrions. +} +\description{ +available_r List available R versions +} +\examples{ +available_r() +} diff --git a/man/find_rev.Rd b/man/find_rev.Rd new file mode 100644 index 00000000..fd6be063 --- /dev/null +++ b/man/find_rev.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/find_rev.R +\name{find_rev} +\alias{find_rev} +\title{find_rev Find the right Nix revision} +\usage{ +find_rev(r_version) +} +\arguments{ +\item{r_version}{Character. R version to look for, for example, "4.2.0"} +} +\value{ +A character. The Nix revision to use +} +\description{ +find_rev Find the right Nix revision +} +\examples{ +find_rev("4.2.0") +} diff --git a/man/rix.Rd b/man/rix.Rd new file mode 100644 index 00000000..0da14562 --- /dev/null +++ b/man/rix.Rd @@ -0,0 +1,47 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/find_rev.R +\name{rix} +\alias{rix} +\title{rix Build a reproducible development environment definition} +\usage{ +rix(r_ver, pkgs, rstudio = FALSE, path = ".") +} +\arguments{ +\item{r_ver}{Character. The required R version. Leave this argument empty if +you want to use the latest R version available. You can check which R +versions are available using \code{available_r}} + +\item{pkgs}{Vector of characters. List the required packages for your +analysis here.} + +\item{rstudio}{Logical, defaults to FALSE. If TRUE, RStudio gets installed in +this environment to enable interactive work.} + +\item{path}{Character. Where to write \code{default.nix}.} +} +\value{ +Nothing, this function only has the side-effect of writing a file +called "default.nix" in the working directory. This file contains the +instructions to build a reproducible environment using the Nix package +manager. +} +\description{ +rix Build a reproducible development environment definition +} +\details{ +This function will write a \code{default.nix} in the chosen path. Using +the Nix package manager, it is then possible to build a reproducible +development environment using the \code{nix-build} command in the path. This +environment will contain the chosen version of R and packages, and will not +interfere with any other installed version (via Nix or not) on your +machine. Every dependency, including both R package dependencies but also +system dependencies like compilers will get installed as well in that +environment. If you use RStudio for interactive work, then set the +\code{rstudio} parameter to \code{TRUE}. If you use another IDE (for example Emacs or +Visual Studio Code), you do not need to add it to the \code{default.nix} file, +you can simply use the version that is installed on your computer. To use +Visual Studio Code however, you need to install the \code{{languageserver}} +package, so don't forget to add it to the list of packages. Once you built +the environment using \code{nix-build}, you can drop into an interactive session +using \code{nix-shell}. See the "How-to Nix" vignette for more details. +} diff --git a/tests/testthat/test-find_rev.R b/tests/testthat/test-find_rev.R new file mode 100644 index 00000000..fa7e8f69 --- /dev/null +++ b/tests/testthat/test-find_rev.R @@ -0,0 +1,6 @@ +# WARNING - Generated by {fusen} from dev/build_envs.Rmd: do not edit by hand + +testthat::expect_equal( + find_rev("4.2.2"), + "8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8" + ) diff --git a/vignettes/dev-build_envs.Rmd b/vignettes/dev-build_envs.Rmd new file mode 100644 index 00000000..b45980ed --- /dev/null +++ b/vignettes/dev-build_envs.Rmd @@ -0,0 +1,40 @@ +--- +title: "dev-build_envs" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{dev-build_envs} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(rix) +``` + + + + + + +This function takes an R version as an input and returns the Nix revision that provides it: + + +This function return available R versions: + + +This next function returns a `default.nix` file that can be used to build a +reproducible environment. This function takes an R version as an input (the +correct Nix revision is found using `find_rev()`), a list of R packages, and +whether the user wants to work with RStudio or not in that environment. If +you use another IDE, you can leave the "rstudio" argument blank: + +