diff --git a/NEWS.md b/NEWS.md index cbb08618..ff429715 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ * `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). * Fixes an issue in pre-defined set of known features: added `either` (#338) +* `create_extendr_package()` allows user to create project directory using RStudio's **Project Command**. (#321) # rextend 0.3.1 diff --git a/R/create_extendr_package.R b/R/create_extendr_package.R new file mode 100644 index 00000000..abee654a --- /dev/null +++ b/R/create_extendr_package.R @@ -0,0 +1,55 @@ + +#' Create package that uses Rust +#' +#' @description +#' This function creates an R project directory for package development +#' with Rust extensions. +#' +#' @inheritParams usethis::create_package +#' @param ... arguments passed on to `usethis::create_package()` and +#' `rextendr::use_extendr()` +#' +#' @return Path to the newly created project or package, invisibly. +#' @keywords internal +#' +#' @noRd +create_extendr_package <- function(path, ...) { + + # error if usethis is not installed + rlang::check_installed("usethis") + + args <- rlang::list2(...) + + # hunch is that rstudio project text input widgets return empty strings + # when no value is given, want to make sure it is NULL so `use_extendr()` + # handles it correctly + nullify_empty_string <- function(x) { + if (rlang::is_string(x) && nzchar(x)) x else NULL + } + + args <- purrr::map(args, nullify_empty_string) + + # build package directory, but don't start a new R session with + # it as the working directory! i.e., set `open = FALSE` + usethis::create_package( + path, + fields = list(), + rstudio = TRUE, + roxygen = args[["roxygen"]] %||% TRUE, + check_name = args[["check_name"]] %||% TRUE, + open = FALSE + ) + + # add rust scaffolding to project dir + use_extendr( + path, + crate_name = args[["crate_name"]], + lib_name = args[["lib_name"]], + quiet = TRUE, + overwrite = TRUE, + edition = args[["edition"]] %||% TRUE + ) + + invisible(path) + +} diff --git a/inst/rstudio/templates/project/extendr.dcf b/inst/rstudio/templates/project/extendr.dcf new file mode 100644 index 00000000..1892f6b5 --- /dev/null +++ b/inst/rstudio/templates/project/extendr.dcf @@ -0,0 +1,33 @@ +Binding: create_extendr_package +Title: R package with extendr +Subtitle: Create an R package with Rust extensions. +Caption: Create an R package with Rust extensions. + +Parameter: roxygen +Widget: CheckboxInput +Label: Use roxygen2 +Default: On +Position: left + +Parameter: check_name +Widget: CheckboxInput +Label: Validate package name +Default: On +Position: left + +Parameter: crate_name +Widget: TextInput +Label: Rust crate name +Position: right + +Parameter: lib_name +Widget: TextInput +Label: Rust library name +Position: right + +Parameter: edition +Widget: SelectInput +Label: Rust edition +Fields: 2021, 2018 +Default: 2021 +Position: right diff --git a/vignettes/package.Rmd b/vignettes/package.Rmd index 9d451e91..3900d73a 100644 --- a/vignettes/package.Rmd +++ b/vignettes/package.Rmd @@ -52,7 +52,11 @@ rextendr::use_extendr() #> • Please run `rextendr::document()` for changes to take effect. ``` -Now we are just one step away from calling Rust functions from R. As the message says, we need to run `rextendr::document()`. +For developers who use RStudio, we also provide a project template that will call `usethis::create_package()` and `rextendr::use_extendr()` for you. This is done using RStudio's **Create Project** command, which you can find on the global toolbar or in the File menu. Choose "New Directory" then select "R package with extendr." You can then fill out the details to match your preferences. + +Once you have the project directory setup, we strongly encourage you to run `rextendr::rust_sitrep()` in the console. This will provide a detailed report of the current state of your Rust infrastructure, along with some helpful advice about how to address any issues that may arise. + +Assuming we have a proper installation of Rust, we are just one step away from calling Rust functions from R. As the message above says, we need to run `rextendr::document()`. But, before moving forward, let's look at the files added. ## Package structure