Skip to content

Commit

Permalink
- Fixed a bug in rix_init() that prevented from writing .Rprofile files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bruno Rodrigues committed Sep 27, 2024
1 parent 62a9fdf commit cdbef0b
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 17 deletions.
38 changes: 28 additions & 10 deletions R/rix_init.R
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,24 @@ rix_init <- function(project_path,
rprofile_quoted <- nix_rprofile()
rprofile_deparsed <- deparse_chr1(expr = rprofile_quoted, collapse = "\n")
rprofile_file <- file.path(project_path, ".Rprofile")
rprofile_con <- file(rprofile_file, open = "wb", encoding = "native.enc")

rprofile_text <- get_rprofile_text(rprofile_deparsed)
on.exit(close(rprofile_con))
write_rprofile <- function(rprofile_text, rprofile_file) {

# This function creates the connection, write the text
# and closes the connection
# Makes it "as pure as possible"
write_rprofile <- function(rprofile_text, rprofile_file, mode) {
create_rprofile_con <- function(rprofile_file, mode) {
rprofile_con <- file(
rprofile_file,
open = mode,
encoding = "native.enc"
)
}

rprofile_con <- create_rprofile_con(rprofile_file, mode)
writeLines(enc2utf8(rprofile_text), rprofile_con, useBytes = TRUE)
on.exit(close(rprofile_con))
}

is_nix_r <- is_nix_r_session()
Expand All @@ -153,7 +165,13 @@ rix_init <- function(project_path,
# signal message if not quiet
message_r_session_nix_rstudio(is_nix_r, is_rstudio, message_type)

rprofile_exists <- file.exists(rprofile_file)
# Test for existence and size instead of only existence,
# as an active file connection makes the file exist, but is empty
# Consider empty files as not existing to avoid not writing
# .Rprofile
rprofile_exists <- file.exists(rprofile_file) &&
`!=`(file.size(rprofile_file), 0L)

timestamp <- format(Sys.time(), "%Y-%m-%dT%H:%M:%S%z")
rprofile_backup <- paste0(rprofile_file, "_backup_", timestamp)

Expand All @@ -167,7 +185,7 @@ rix_init <- function(project_path,
)
}
} else {
write_rprofile(rprofile_text, rprofile_file = rprofile_con)
write_rprofile(rprofile_text, rprofile_file = rprofile_file, mode = "wb")
if (isFALSE(is_quiet)) {
message_rprofile(action_string = "Added", project_path = project_path)
}
Expand All @@ -177,7 +195,7 @@ rix_init <- function(project_path,
create_backup = {
if (isTRUE(rprofile_exists)) {
file.copy(from = rprofile_file, to = rprofile_backup)
write_rprofile(rprofile_text, rprofile_file = rprofile_con)
write_rprofile(rprofile_text, rprofile_file = rprofile_file, mode = "wb")
if (isFALSE(is_quiet)) {
cat(
"\n==> Backed up existing `.Rprofile` in file:\n", rprofile_backup,
Expand All @@ -191,13 +209,13 @@ rix_init <- function(project_path,

if (message_type == "verbose") {
cat("\n* Current lines of local `.Rprofile` are\n:")
cat(readLines(con = rprofile_con), sep = "\n")
cat(readLines(con = rprofile_file), sep = "\n")
}
set_message_session_PATH(message_type = message_type)
}
},
overwrite = {
write_rprofile(rprofile_text, rprofile_file = rprofile_con)
write_rprofile(rprofile_text, rprofile_file = rprofile_file, mode = "wb")
if (isTRUE(rprofile_exists)) {
message_rprofile(
action_string = "Overwrote", project_path = project_path
Expand All @@ -209,7 +227,7 @@ rix_init <- function(project_path,
}
},
append = {
cat(paste0(rprofile_text, "\n"), file = rprofile_con, append = TRUE)
write_rprofile(rprofile_text, rprofile_file = rprofile_file, mode = "a+")
message_rprofile(
action_string = "Appended", project_path = project_path
)
Expand All @@ -218,7 +236,7 @@ rix_init <- function(project_path,

if (message_type == "verbose") {
cat("\n\n* Current lines of local `.Rprofile` are:\n\n")
cat(readLines(con = rprofile_action), sep = "\n")
cat(readLines(con = rprofile_file), sep = "\n")
}
}

Expand Down
3 changes: 2 additions & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ While Nix has a steep learning curve, `{rix}`
same code in different development environments, and finally to deploy
software environments in production.

If you want to watch a 5-Minute video introduction click [here](https://www.youtube.com/embed/OOu6gjQ310c?si=tQ-s9ZgEBxak8k8G).
If you want to watch a 5-Minute video introduction click
[here](https://youtu.be/OOu6gjQ310c?si=qQ5lUhAg5U-WT2W1).

Nix includes nearly all CRAN and Bioconductor packages, with the ability to
install specific package versions or GitHub snapshots. Nix also includes Python,
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ While Nix has a steep learning curve, `{rix}`
finally to deploy software environments in production.

If you want to watch a 5-Minute video introduction click
[here](https://www.youtube.com/embed/OOu6gjQ310c?si=tQ-s9ZgEBxak8k8G).
[here](https://youtu.be/OOu6gjQ310c?si=qQ5lUhAg5U-WT2W1).

Nix includes nearly all CRAN and Bioconductor packages, with the ability
to install specific package versions or GitHub snapshots. Nix also
Expand Down
8 changes: 4 additions & 4 deletions inst/extdata/default.nix
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# This file was generated by the {rix} R package v0.12.2 on 2024-09-26
# This file was generated by the {rix} R package v0.12.3 on 2024-09-27
# with following call:
# >rix(r_ver = "976fa3369d722e76f37c77493d99829540d43845",
# > git_pkgs = list(package_name = "rix",
# > repo_url = "https://github.com/ropensci/rix/",
# > commit = "d576259a2601dd6036dc85d110581784d753e622"),
# > commit = "f69c72dc7d27d12ab65ce1a7c48e541d3097bf69"),
# > ide = "other",
# > project_path = "inst/extdata",
# > overwrite = TRUE)
Expand All @@ -18,8 +18,8 @@ let
name = "rix";
src = pkgs.fetchgit {
url = "https://github.com/ropensci/rix/";
rev = "d576259a2601dd6036dc85d110581784d753e622";
sha256 = "sha256-Tb/4qNwKYoMnd3KZ/Y4rXKKtmeF6n92JBy9ztXAG1pY=";
rev = "f69c72dc7d27d12ab65ce1a7c48e541d3097bf69";
sha256 = "sha256-PIY5z3/GmXMIpwRNfvooyxih0/hTbYPL5Q1cD2U/og0=";
};
propagatedBuildInputs = builtins.attrValues {
inherit (pkgs.rPackages)
Expand Down
42 changes: 42 additions & 0 deletions tests/testthat/_snaps/rix_init/append_Rprofile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
This is in the original Rprofile
### File generated by `rix::rix_init()` ###
# 1. Currently, system RStudio does not inherit environmental variables
# defined in `$HOME/.zshrc`, `$HOME/.bashrc` and alike. This is workaround to
# make the path of the nix store and hence basic nix commands available
# in an RStudio session
# 2. For nix-R session, remove `R_LIBS_USER`, system's R user library.`.
# This guarantees no user libraries from the system are loaded and only
# R packages in the Nix store are used. This makes Nix-R behave in pure manner
# at run-time.
{
is_rstudio <- Sys.getenv("RSTUDIO") == "1"
is_nix_r <- nzchar(Sys.getenv("NIX_STORE"))
if (isFALSE(is_nix_r) && isTRUE(is_rstudio)) {
cat("{rix} detected RStudio R session")
old_path <- Sys.getenv("PATH")
nix_path <- "/nix/var/nix/profiles/default/bin"
has_nix_path <- any(grepl(nix_path, old_path))
if (isFALSE(has_nix_path)) {
Sys.setenv(PATH = paste(old_path, nix_path, sep = ":"))
}
rm(old_path, nix_path)
}
if (isTRUE(is_nix_r)) {
install.packages <- function(...) {
stop("You are currently in an R session running from Nix.\n", "Don't install packages using install.packages(),\nadd them to ", "the default.nix file instead.")
}
update.packages <- function(...) {
stop("You are currently in an R session running from Nix.\n", "Don't update packages using update.packages(),\n", "generate a new default.nix with a more recent version of R. ", "If you need bleeding edge packages, read the", "'Understanding the rPackages set release cycle and using ", "bleeding edge packages' vignette.")
}
remove.packages <- function(...) {
stop("You are currently in an R session running from Nix.\n", "Don't remove packages using `remove.packages()``,\ndelete them ", "from the default.nix file instead.")
}
current_paths <- .libPaths()
userlib_paths <- Sys.getenv("R_LIBS_USER")
user_dir <- grep(paste(userlib_paths, collapse = "|"), current_paths, fixed = TRUE)
new_paths <- current_paths[-user_dir]
.libPaths(new_paths)
rm(current_paths, userlib_paths, user_dir, new_paths)
}
rm(is_rstudio, is_nix_r)
}
101 changes: 100 additions & 1 deletion tests/testthat/test-rix_init.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
testthat::test_that("Snapshot test of rix_init()", {
testthat::test_that("Snapshot test of rix_init(), overwrite", {
path_env_nix <- tempdir()

# Create an empty file, and overwrite it
rprofile_file <- paste0(path_env_nix, "/.Rprofile")

save_rix_init_test <- function(path_env_nix) {
rix_init(
project_path = path_env_nix,
Expand All @@ -11,8 +14,69 @@ testthat::test_that("Snapshot test of rix_init()", {
paste0(path_env_nix, "/.Rprofile")
}

rprofile_con <- file(rprofile_file, open = "wb", encoding = "native.enc")
on.exit(close(rprofile_con), add = TRUE)

testthat::expect_snapshot_file(
path = save_rix_init_test(path_env_nix),
name = "golden_Rprofile.txt",
)

on.exit(
unlink(path_env_nix, recursive = TRUE, force = TRUE),
add = TRUE
)
})


testthat::test_that("Snapshot test of rix_init(), create_missing, no file", {
path_env_nix <- tempdir()

save_rix_init_test <- function(path_env_nix) {
rix_init(
project_path = path_env_nix,
rprofile_action = "create_missing",
message_type = "simple"
)

paste0(path_env_nix, "/.Rprofile")
}

testthat::expect_snapshot_file(
path = save_rix_init_test(path_env_nix),
name = "golden_Rprofile.txt",
)

on.exit(
unlink(path_env_nix, recursive = TRUE, force = TRUE),
add = TRUE
)
})

testthat::test_that("Snapshot test of rix_init(), create_missing, empty file", {
# Empty should be considered as missing
# We're creating an empty .Rprofile by opening a file connection
# and then rix_init() should consider it missing and write

path_env_nix <- tempdir()

rprofile_file <- paste0(path_env_nix, "/.Rprofile")

save_rix_init_test <- function(path_env_nix) {
rix_init(
project_path = path_env_nix,
rprofile_action = "create_missing",
message_type = "simple"
)

rprofile_file
}

testthat::announce_snapshot_file("find_rev/golden_Rprofile.txt")

rprofile_con <- file(rprofile_file, open = "wb", encoding = "native.enc")
on.exit(close(rprofile_con), add = TRUE)

testthat::expect_snapshot_file(
path = save_rix_init_test(path_env_nix),
name = "golden_Rprofile.txt",
Expand All @@ -23,3 +87,38 @@ testthat::test_that("Snapshot test of rix_init()", {
add = TRUE
)
})


testthat::test_that("Snapshot test of rix_init(), append", {
path_env_nix <- tempdir()

save_rix_init_test <- function(path_env_nix) {
rix_init(
project_path = path_env_nix,
rprofile_action = "append",
message_type = "simple"
)

paste0(path_env_nix, "/.Rprofile")
}

rprofile_file <- paste0(path_env_nix, "/.Rprofile")
rprofile_con <- file(rprofile_file, open = "a+", encoding = "native.enc")

writeLines(enc2utf8("This is in the original Rprofile"),
rprofile_con,
useBytes = TRUE
)

close(rprofile_con)

testthat::expect_snapshot_file(
path = save_rix_init_test(path_env_nix),
name = "append_Rprofile.txt",
)

on.exit(
unlink(path_env_nix, recursive = TRUE, force = TRUE),
add = TRUE
)
})

0 comments on commit cdbef0b

Please sign in to comment.