diff --git a/DESCRIPTION b/DESCRIPTION index 14e86e89..393411e4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -10,7 +10,7 @@ License: GPL (>= 3) Depends: R (>= 2.10) Imports: - magrittr + utils Suggests: dplyr, janitor, diff --git a/NAMESPACE b/NAMESPACE index 5da41b13..acff3b04 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,8 +1,6 @@ # Generated by roxygen2: do not edit by hand -export("%>%") export(available_r) export(find_rev) -export(my_fun) export(rix) -importFrom(magrittr,"%>%") +importFrom(utils,data) diff --git a/NEWS.md b/NEWS.md index 2f98f1a1..a6e1d8bc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,3 @@ # rix (development version) -* Initial CRAN submission. +* Basic functionality added. diff --git a/R/my_fun.R b/R/my_fun.R deleted file mode 100644 index eededa75..00000000 --- a/R/my_fun.R +++ /dev/null @@ -1,12 +0,0 @@ -# WARNING - Generated by {fusen} from dev/flat_minimal_package.Rmd: do not edit by hand - -#' my_fun Title -#' -#' @return 1 -#' @export -#' -#' @examples -#' my_fun() -my_fun <- function() { - 1 -} diff --git a/R/rix-package.R b/R/rix-package.R deleted file mode 100644 index a65cf643..00000000 --- a/R/rix-package.R +++ /dev/null @@ -1,6 +0,0 @@ -#' @keywords internal -"_PACKAGE" - -## usethis namespace: start -## usethis namespace: end -NULL diff --git a/R/utils-pipe.R b/R/utils-pipe.R deleted file mode 100644 index fd0b1d13..00000000 --- a/R/utils-pipe.R +++ /dev/null @@ -1,14 +0,0 @@ -#' Pipe operator -#' -#' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. -#' -#' @name %>% -#' @rdname pipe -#' @keywords internal -#' @export -#' @importFrom magrittr %>% -#' @usage lhs \%>\% rhs -#' @param lhs A value or the magrittr placeholder. -#' @param rhs A function call using the magrittr semantics. -#' @return The result of calling `rhs(lhs)`. -NULL diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 00000000..8b1be328 --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,7 @@ +# WARNING - Generated by {fusen} from dev/zzz.Rmd: do not edit by hand + +#' zzz +#' +#' Global imports +#' @importFrom utils data +utils::globalVariables(c("r_nix_revs")) diff --git a/README.Rmd b/README.Rmd index 7ffffdd5..b105fcf4 100644 --- a/README.Rmd +++ b/README.Rmd @@ -13,13 +13,114 @@ knitr::opts_chunk$set( ) ``` -# rix +# Rix: Reproducible Environments with Nix + +## Introduction [![R-CMD-check](https://github.com/b-rodrigues/rix/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/b-rodrigues/rix/actions/workflows/R-CMD-check.yaml) -The goal of rix is to ... +**WARNING: This package is in very early development. I've literally have only +worked 4 hours on it. DO NOT USE IT!** + +`{rix}` is an R package that provides helper functions to help you setup +development environments that contain all the required packages that you need +for your project. This is achieved by using the Nix package manager that you +must install separately. The Nix package manager is extremely powerful: with it, +it is possible to work on totally reproducible development environments, and +even install old releases of R and R packages. With Nix, it is essentially +possible to replace `{renv}` and Docker combined. Nix is available for Linux, +macOS and Windows. + +## The Nix package manager + +Nix is a piece of software 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 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* 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, and then +continue working on that isolated environment. It is possible to have as many +environments as projects. Each environment is isolated (or not, it's up to you). + +The main function of `{rix}` is called `rix()`. `rix()` has 4 arguments: + +- the R version you need for your project +- a list of R packages that your project needs +- whether you want to use RStudio as an IDE for your project +- a path to save a file called `default.nix`. + +### 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`. To make it easier for R programmers to use Nix, `{rix}` can be +used to write this file for you. Once this file has been written, 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 done building the environment, you can start working on it interactively +by using the following command: + +``` +nix-shell +``` + +You will *drop* in 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. + +### Running programs from an environment + +You could create a bash script that you put in the path to make this process +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: + +``` +nix-shell /absolute/path/to/housing/default.nix --run Rscript -e 'targets::tar_make()' +``` ## Installation diff --git a/README.md b/README.md new file mode 100644 index 00000000..7819fe35 --- /dev/null +++ b/README.md @@ -0,0 +1,150 @@ + + + +# Rix: Reproducible Environments with Nix + +## Introduction + + + +[![R-CMD-check](https://github.com/b-rodrigues/rix/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/b-rodrigues/rix/actions/workflows/R-CMD-check.yaml) + + +**WARNING: This package is in very early development. I’ve literally +have only worked 4 hours on it. DO NOT USE IT\!** + +`{rix}` is an R package that provides helper functions to help you setup +development environments that contain all the required packages that you +need for your project. This is achieved by using the Nix package manager +that you must install separately. The Nix package manager is extremely +powerful: with it, it is possible to work on totally reproducible +development environments, and even install old releases of R and R +packages. With Nix, it is essentially possible to replace `{renv}` and +Docker combined. Nix is available for Linux, macOS and Windows. + +## The Nix package manager + +Nix is a piece of software 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 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* 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, and +then continue working on that isolated environment. It is possible to +have as many environments as projects. Each environment is isolated (or +not, it’s up to you). + +The main function of `{rix}` is called `rix()`. `rix()` has 4 arguments: + + - the R version you need for your project + - a list of R packages that your project needs + - whether you want to use RStudio as an IDE for your project + - a path to save a file called `default.nix`. + +### 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`. To make it easier for R programmers to use Nix, `{rix}` +can be used to write this file for you. Once this file has been written, +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 done building the environment, you can start working on it +interactively by using the following command: + + nix-shell + +You will *drop* in 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. + +### Running programs from an environment + +You could create a bash script that you put in the path to make this +process 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: + + nix-shell /absolute/path/to/housing/default.nix --run Rscript -e 'targets::tar_make()' + +## Installation + +You can install the development version of rix from +[GitHub](https://github.com/) with: + +``` r +# install.packages("devtools") +devtools::install_github("b-rodrigues/rix") +``` + +## Example + +This is a basic example which shows you how to solve a common problem: + +``` r +library(rix) +## basic example code +``` + +What is special about using `README.Rmd` instead of just `README.md`? +You can include R chunks like so: + +``` r +summary(cars) +#> speed dist +#> Min. : 4.0 Min. : 2.00 +#> 1st Qu.:12.0 1st Qu.: 26.00 +#> Median :15.0 Median : 36.00 +#> Mean :15.4 Mean : 42.98 +#> 3rd Qu.:19.0 3rd Qu.: 56.00 +#> Max. :25.0 Max. :120.00 +``` + +You’ll still need to render `README.Rmd` regularly, to keep `README.md` +up-to-date. `devtools::build_readme()` is handy for this. + +You can also embed plots, for example: + + + +In that case, don’t forget to commit and push the resulting figure +files, so they display on GitHub and CRAN. diff --git a/dev/0-dev_history.Rmd b/dev/0-dev_history.Rmd index 12616f2f..d9b89bf7 100755 --- a/dev/0-dev_history.Rmd +++ b/dev/0-dev_history.Rmd @@ -19,7 +19,7 @@ fusen::fill_description( Title = "Rix: Reproducible Environments with Nix", Description = "Provides helper functions to create reproducible development environments using the Nix package manager.", `Authors@R` = c( - person("Bruno", "Rodrigues", email = "brodriguesco@protonmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3211-3689")) + person("Bruno", "Rodrigues", email = "bruno@brodrigues.co", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3211-3689")) ) ) ) @@ -94,6 +94,12 @@ fusen::inflate(flat_file = "dev/data_doc.Rmd", overwrite = TRUE) ``` +```{r} +fusen::inflate(flat_file = "dev/zzz.Rmd", + vignette_name = NA, + overwrite = TRUE) +``` + # Package development tools ## Use once diff --git a/dev/build_envs.Rmd b/dev/build_envs.Rmd index fdea6db6..3147ecaf 100644 --- a/dev/build_envs.Rmd +++ b/dev/build_envs.Rmd @@ -1,5 +1,5 @@ --- -title: "RIX: functions" +title: "Build envs" output: html_document editor_options: chunk_output_type: console diff --git a/dev/config_fusen.yaml b/dev/config_fusen.yaml index 413db6da..1e06abc7 100644 --- a/dev/config_fusen.yaml +++ b/dev/config_fusen.yaml @@ -24,19 +24,6 @@ data_doc.Rmd: check: true document: true overwrite: 'yes' -flat_minimal_package.Rmd: - path: dev/flat_minimal_package.Rmd - state: active - R: R/my_fun.R - tests: tests/testthat/test-my_fun.R - vignettes: vignettes/minimal.Rmd - inflate: - flat_file: dev/flat_minimal_package.Rmd - vignette_name: Minimal - open_vignette: true - check: true - document: true - overwrite: ask save_r_nix_revs.Rmd: path: dev/save_r_nix_revs.Rmd state: active @@ -50,3 +37,16 @@ save_r_nix_revs.Rmd: 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: true + overwrite: 'yes' diff --git a/dev/config_not_registered.csv b/dev/config_not_registered.csv new file mode 100644 index 00000000..6482d100 --- /dev/null +++ b/dev/config_not_registered.csv @@ -0,0 +1,2 @@ +"type","path","origin" +"R","R/zzz.R","Possibly deprecated file. Please check its link with detected flat source: dev/zzz.Rmd" diff --git a/dev/save_r_nix_revs.Rmd b/dev/save_r_nix_revs.Rmd index 175caebc..df829853 100644 --- a/dev/save_r_nix_revs.Rmd +++ b/dev/save_r_nix_revs.Rmd @@ -1,5 +1,5 @@ --- -title: "Get the Nix revisions for old releases of R" +title: "Save the Nix Package Versions data" output: html_document editor_options: chunk_output_type: console diff --git a/dev/zzz.Rmd b/dev/zzz.Rmd new file mode 100644 index 00000000..2998fc7d --- /dev/null +++ b/dev/zzz.Rmd @@ -0,0 +1,16 @@ +--- +title: "ZZZ" +output: html_document +editor_options: + chunk_output_type: console +--- + +## zzz + +```{r function-zzz, eval = F} +#' zzz +#' +#' Global imports +#' @importFrom utils data +utils::globalVariables(c("r_nix_revs")) +``` diff --git a/man/figures/README-pressure-1.png b/man/figures/README-pressure-1.png new file mode 100644 index 00000000..b1318d48 Binary files /dev/null and b/man/figures/README-pressure-1.png differ diff --git a/man/my_fun.Rd b/man/my_fun.Rd deleted file mode 100644 index b69e2839..00000000 --- a/man/my_fun.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/my_fun.R -\name{my_fun} -\alias{my_fun} -\title{my_fun Title} -\usage{ -my_fun() -} -\value{ -1 -} -\description{ -my_fun Title -} -\examples{ -my_fun() -} diff --git a/man/pipe.Rd b/man/pipe.Rd deleted file mode 100644 index a648c296..00000000 --- a/man/pipe.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/utils-pipe.R -\name{\%>\%} -\alias{\%>\%} -\title{Pipe operator} -\usage{ -lhs \%>\% rhs -} -\arguments{ -\item{lhs}{A value or the magrittr placeholder.} - -\item{rhs}{A function call using the magrittr semantics.} -} -\value{ -The result of calling \code{rhs(lhs)}. -} -\description{ -See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. -} -\keyword{internal} diff --git a/man/rix-package.Rd b/man/rix-package.Rd deleted file mode 100644 index ac35ecd7..00000000 --- a/man/rix-package.Rd +++ /dev/null @@ -1,15 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/rix-package.R -\docType{package} -\name{rix-package} -\alias{rix} -\alias{rix-package} -\title{rix: Rix: Reproducible Environments With Nix} -\description{ -Provides helper functions to create reproducible development environments using the Nix package manager. -} -\author{ -\strong{Maintainer}: Bruno Rodrigues \email{brodriguesco@protonmail.com} (\href{https://orcid.org/0000-0002-3211-3689}{ORCID}) - -} -\keyword{internal} diff --git a/tests/testthat/test-my_fun.R b/tests/testthat/test-my_fun.R deleted file mode 100644 index e650303d..00000000 --- a/tests/testthat/test-my_fun.R +++ /dev/null @@ -1,5 +0,0 @@ -# WARNING - Generated by {fusen} from dev/flat_minimal_package.Rmd: do not edit by hand - -test_that("my_fun works", { - -}) diff --git a/vignettes/minimal.Rmd b/vignettes/minimal.Rmd deleted file mode 100644 index f593393c..00000000 --- a/vignettes/minimal.Rmd +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "Minimal" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{minimal} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -``` - -```{r setup} -library(rix) -``` - - - - - - -# my_fun - -```{r examples-my_fun} -my_fun() -``` -