diff --git a/R/use_crate.R b/R/use_crate.R index cea33920..66496a7c 100644 --- a/R/use_crate.R +++ b/R/use_crate.R @@ -52,27 +52,33 @@ use_crate <- function( check_bool(optional) check_string(path) + if (!is.null(version) && !is.null(git)) { + cli::cli_abort( + "Cannot specify a git URL ('{git}') with a version ('{version}').", + class = "rextendr_error" + ) + } + if (!is.null(version)) { crate <- paste0(crate, "@", version) } - # combine main options - cargo_add_opts <- list( - "--features" = paste0(features, collapse = " "), - "--git" = git, - "--optional" = tolower(as.character(optional)) - ) + if (!is.null(features)) { + features <- c( + "--features", + paste(crate, features, sep = "/", collapse = ",") + ) + } - # clear empty options - cargo_add_opts <- purrr::discard(cargo_add_opts, rlang::is_empty) + if (!is.null(git)) { + git <- c("--git", git) + } - # combine option names and values into single strings - adtl_args <- unname(purrr::imap_chr( - cargo_add_opts, - function(x, i) { - paste(i, paste0(x, collapse = " ")) - } - )) + if (optional) { + optional <- "--optional" + } else { + optional <- NULL + } # get rust directory in project folder root <- rprojroot::find_package_root_file(path = path) @@ -86,7 +92,7 @@ use_crate <- function( # run the commmand processx::run( "cargo", - c("add", crate, adtl_args), + c("add", crate, features, git, optional), echo_cmd = TRUE, wd = rust_folder ) diff --git a/tests/testthat/test-use_crate.R b/tests/testthat/test-use_crate.R new file mode 100644 index 00000000..b3419279 --- /dev/null +++ b/tests/testthat/test-use_crate.R @@ -0,0 +1,97 @@ +test_that("use_crate() adds dependency to package or workspace", { + skip_if_not_installed("usethis") + + path <- local_package("testpkg") + + # capture setup messages + withr::local_options(usethis.quiet = FALSE) + + use_extendr(path, quiet = TRUE) + + use_crate( + "serde", + features = "derive", + version = "1.0.1", + path = path + ) + + metadata <- read_cargo_metadata(path) + + dependency <- metadata[["packages"]][["dependencies"]][[1]] + dependency <- dependency[dependency[["name"]] == "serde", ] + + expect_equal(dependency[["name"]], "serde") + + expect_equal(dependency[["features"]][[1]], "derive") + + expect_equal(dependency[["req"]], "^1.0.1") +}) + +test_that("use_crate() errors when user passes git and version arguments", { + skip_if_not_installed("usethis") + + path <- local_package("testpkg") + + # capture setup messages + withr::local_options(usethis.quiet = FALSE) + + use_extendr(path, quiet = TRUE) + + fn <- function() { + use_crate( + "serde", + git = "https://github.com/serde-rs/serde", + version = "1.0.1" + ) + } + + expect_error(fn(), class = "rextendr_error") +}) + +test_that("use_crate(optional = TRUE) adds optional dependency", { + skip_if_not_installed("usethis") + + path <- local_package("testpkg") + + # capture setup messages + withr::local_options(usethis.quiet = FALSE) + + use_extendr(path, quiet = TRUE) + + use_crate( + "serde", + optional = TRUE, + path = path + ) + + metadata <- read_cargo_metadata(path) + + dependency <- metadata[["packages"]][["dependencies"]][[1]] + dependency <- dependency[dependency[["name"]] == "serde", ] + + expect_identical(dependency[["optional"]], TRUE) +}) + +test_that("use_crate(git = ) adds dependency with git source", { + skip_if_not_installed("usethis") + + path <- local_package("testpkg") + + # capture setup messages + withr::local_options(usethis.quiet = FALSE) + + use_extendr(path, quiet = TRUE) + + use_crate( + "serde", + git = "https://github.com/serde-rs/serde", + path = path + ) + + metadata <- read_cargo_metadata(path) + + dependency <- metadata[["packages"]][["dependencies"]][[1]] + dependency <- dependency[dependency[["name"]] == "serde", ] + + expect_equal(dependency[["source"]], "git+https://github.com/serde-rs/serde") +})