Skip to content

Commit

Permalink
[Bugfix] Correctly handle use_extendr(custom_path) (#323)
Browse files Browse the repository at this point in the history
* Prototype test

* Fix paths in setup.R

* Temporarily setup local project

* Checking if current path is usethis project path

* Fix paths issue

* Move test to the shared file

* NEWS.md
  • Loading branch information
Ilia-Kosenkov authored Nov 19, 2023
1 parent 8c572fb commit 09bfeba
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 18 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
`Cargo (rustc package manager)` if the field is empty (#298).
* `use_extendr()` gets a new ability to overwrite existing rextendr templates (#292).
* `use_extendr()` sets `publish = false` in the `[package]` section of the `Cargo.toml` (#297).
* `use_extendr()` correctly handles calls with `path` not equal to `"."` (current folder), or when there is no active `{usethis}` project (#323).

# rextend 0.3.1

Expand Down
29 changes: 15 additions & 14 deletions R/setup.R
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
rextendr_setup <- function(path = ".", cur_version = NULL) {
if (!file.exists(file.path(path, "DESCRIPTION"))) {
desc_path <- rprojroot::find_package_root_file("DESCRIPTION", path = path)
if (!file.exists(desc_path)) {
cli::cli_abort(
"{.arg path} ({.path {path}}) does not contain a DESCRIPTION",
class = "rextendr_error"
)
}

is_first <- is.na(rextendr_version(path))
is_first <- is.na(rextendr_version(desc_path = desc_path))

if (is_first) {
cli::cli_alert_info("First time using rextendr. Upgrading automatically...")
}

update_rextendr_version(path, cur_version = cur_version)
update_sys_reqs(path)
update_rextendr_version(desc_path = desc_path, cur_version = cur_version)
update_sys_reqs(desc_path = desc_path)

invisible(TRUE)
}

update_rextendr_version <- function(path, cur_version = NULL) {
update_rextendr_version <- function(desc_path, cur_version = NULL) {
cur <- cur_version %||% as.character(utils::packageVersion("rextendr"))
prev <- rextendr_version(path)
prev <- rextendr_version(desc_path = desc_path)

if (!is.na(cur) && !is.na(prev) && package_version(cur) < package_version(prev)) {
cli::cli_alert_warning(c(
"Installed rextendr is older than the version used with this package",
"You have {.str {cur}} but you need {.str {prev}}"
))
} else if (!identical(cur, prev)) {
update_description("Config/rextendr/version", cur)
update_description("Config/rextendr/version", cur, desc_path = desc_path)
}
}

update_sys_reqs <- function(path) {
update_sys_reqs <- function(desc_path) {
cur <- "Cargo (rustc package manager)"
prev <- stringi::stri_trim_both(desc::desc_get("SystemRequirements", path)[[1]])
prev <- stringi::stri_trim_both(desc::desc_get("SystemRequirements", file = desc_path)[[1]])

if (is.na(prev)) {
update_description("SystemRequirements", cur)
update_description("SystemRequirements", cur, desc_path = desc_path)
} else if (!identical(cur, prev)) {
cli::cli_ul(
c(
Expand All @@ -48,11 +49,11 @@ update_sys_reqs <- function(path) {
}
}

update_description <- function(field, value) {
update_description <- function(field, value, desc_path) {
cli::cli_alert_info("Setting {.var {field}} to {.str {value}} in the {.file DESCRIPTION} file.")
desc::desc_set(field, value)
desc::desc_set(field, value, file = desc_path)
}

rextendr_version <- function(path = ".") {
stringi::stri_trim_both(desc::desc_get("Config/rextendr/version", path)[[1]])
rextendr_version <- function(desc_path = ".") {
stringi::stri_trim_both(desc::desc_get("Config/rextendr/version", desc_path)[[1]])
}
44 changes: 40 additions & 4 deletions R/use_extendr.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,32 @@ use_extendr <- function(path = ".",

rlang::check_installed("usethis")

rextendr_setup(path = path)
# Root path computed from user input
root_path <- try_get_root_path(path)
# Root path computed from `{usethis}`
usethis_proj_path <- try_get_proj_path()

# If they do not match, something is off, try to set up temporary project
if (!isTRUE(root_path == usethis_proj_path)) {
usethis::local_project(path, quiet = quiet)
}

# Check project path once again
usethis_proj_path <- try_get_proj_path()
# Check what is current working directory
curr_path <- try_get_normalized_path(getwd)

# If they do not match, let's temporarily change working directory
if (!isTRUE(curr_path == usethis_proj_path)) {
withr::local_dir(usethis_proj_path)
}

pkg_name <- pkg_name(path)
# At this point, our working directory is at the project root and
# we have an active `{usethis}` project

rextendr_setup()

pkg_name <- pkg_name()
mod_name <- as_valid_rust_name(pkg_name)

if (is.null(crate_name)) {
Expand All @@ -54,8 +77,9 @@ use_extendr <- function(path = ".",
throw_if_invalid_rust_name(lib_name)
}

src_dir <- rprojroot::find_package_root_file("src", path = path)
r_dir <- rprojroot::find_package_root_file("R", path = path)
src_dir <- rprojroot::find_package_root_file("src")
r_dir <- rprojroot::find_package_root_file("R")


if (!dir.exists(r_dir)) {
dir.create(r_dir)
Expand Down Expand Up @@ -160,6 +184,18 @@ use_extendr <- function(path = ".",
return(invisible(TRUE))
}

try_get_normalized_path <- function(path_fn) {
tryCatch(normalizePath(path_fn(), winslash = "/", mustWork = FALSE), error = function(e) NA)
}

try_get_proj_path <- function() {
try_get_normalized_path(usethis::proj_get)
}

try_get_root_path <- function(path) {
try_get_normalized_path(function() rprojroot::find_package_root_file(path = path))
}

#' Checks if provided name is a valid Rust name (identifier)
#'
#' @param name \[ character(n) \] Names to test.
Expand Down
9 changes: 9 additions & 0 deletions tests/testthat/test-use_extendr.R
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,12 @@ test_that("Message if the SystemRequirements field is already set.", {
expect_true(created)
expect_equal(desc::desc_get("SystemRequirements")[[1]], sys_req)
})

test_that("`use_extendr()` works correctly when path is specified explicitly", {
skip_if_not_installed("usethis")
local_temp_dir("temp_dir")
usethis::create_package("testpkg")

use_extendr(path = "testpkg")
succeed()
})

0 comments on commit 09bfeba

Please sign in to comment.