Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix rix_init not writing Rprofile #342

Merged
merged 11 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
)
})
Loading