From ea68f4ef05fedb5d0d1966f1517fc6cfac9e0944 Mon Sep 17 00:00:00 2001 From: Kenneth Blake Vernon <53311626+kbvernon@users.noreply.github.com> Date: Sat, 9 Nov 2024 09:37:17 -0700 Subject: [PATCH] Read cargo metadata (#389) * draft and test * use expect_type() * list under utility functions * document * check string * more meaningful test * update news * Update NEWS.md Co-authored-by: Ilia Kosenkov --------- Co-authored-by: Ilia Kosenkov --- NAMESPACE | 1 + NEWS.md | 2 + R/read_cargo_metadata.R | 46 +++++++++++++++++++++++ _pkgdown.yml | 1 + man/read_cargo_metadata.Rd | 39 +++++++++++++++++++ tests/testthat/test-read_cargo_metadata.R | 38 +++++++++++++++++++ 6 files changed, 127 insertions(+) create mode 100644 R/read_cargo_metadata.R create mode 100644 man/read_cargo_metadata.Rd create mode 100644 tests/testthat/test-read_cargo_metadata.R diff --git a/NAMESPACE b/NAMESPACE index b04fbc0d..6154edb7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,6 +14,7 @@ export(document) export(eng_extendr) export(eng_extendrsrc) export(make_module_macro) +export(read_cargo_metadata) export(register_extendr) export(rust_eval) export(rust_function) diff --git a/NEWS.md b/NEWS.md index 246de4ea..8438f966 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,6 +17,8 @@ * Fixed an issue in `rust_source()` family of functions that prevented usage of `r#` escape sequences in Rust function names (#374) * `use_cran_defaults()` now checks the `SystemRequirements` field in the `DESCRIPTION` file for cargo and rustc. It will display installation instructions if either is missing or provide the minimum required version if the installed version is outdated. * Added `use_msrv()` to aid in specifying the minimum supported rust version (MSRV) for an R package +* Added `read_cargo_metadata()` to retrieve Cargo metadata for packages and + workspaces. (#389) # rextend 0.3.1 diff --git a/R/read_cargo_metadata.R b/R/read_cargo_metadata.R new file mode 100644 index 00000000..4e314c3d --- /dev/null +++ b/R/read_cargo_metadata.R @@ -0,0 +1,46 @@ +#' Retrieve metadata for packages and workspaces +#' +#' @param path character scalar, the R package directory +#' +#' @details +#' For more details, see +#' \href{https://doc.rust-lang.org/cargo/commands/cargo-metadata.html}{Cargo docs} +#' for `cargo-metadata`. See especially "JSON Format" to get a sense of what you +#' can expect to find in the returned list. +#' +#' @return `list`, including the following elements: +#' - "packages" +#' - "workspace_members" +#' - "workspace_default_members" +#' - "resolve" +#' - "target_directory" +#' - "version" +#' - "workspace_root" +#' - "metadata" +#' +#' @export +#' +#' @examples +#' \dontrun{ +#' read_cargo_metadata() +#' } +#' +read_cargo_metadata <- function(path = ".") { + check_string(path, class = "rextendr_error") + + root <- rprojroot::find_package_root_file(path = path) + + rust_folder <- normalizePath( + file.path(root, "src", "rust"), + winslash = "/", + mustWork = FALSE + ) + + out <- processx::run( + "cargo", + args = c("metadata", "--format-version=1", "--no-deps"), + wd = rust_folder + ) + + jsonlite::fromJSON(out[["stdout"]]) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index eddfcfa1..74a0ad15 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -29,3 +29,4 @@ reference: - to_toml - make_module_macro - rust_sitrep + - read_cargo_metadata diff --git a/man/read_cargo_metadata.Rd b/man/read_cargo_metadata.Rd new file mode 100644 index 00000000..70d20284 --- /dev/null +++ b/man/read_cargo_metadata.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/read_cargo_metadata.R +\name{read_cargo_metadata} +\alias{read_cargo_metadata} +\title{Retrieve metadata for packages and workspaces} +\usage{ +read_cargo_metadata(path = ".") +} +\arguments{ +\item{path}{character scalar, the R package directory} +} +\value{ +\code{list}, including the following elements: +\itemize{ +\item "packages" +\item "workspace_members" +\item "workspace_default_members" +\item "resolve" +\item "target_directory" +\item "version" +\item "workspace_root" +\item "metadata" +} +} +\description{ +Retrieve metadata for packages and workspaces +} +\details{ +For more details, see +\href{https://doc.rust-lang.org/cargo/commands/cargo-metadata.html}{Cargo docs} +for \code{cargo-metadata}. See especially "JSON Format" to get a sense of what you +can expect to find in the returned list. +} +\examples{ +\dontrun{ +read_cargo_metadata() +} + +} diff --git a/tests/testthat/test-read_cargo_metadata.R b/tests/testthat/test-read_cargo_metadata.R new file mode 100644 index 00000000..6ec99b6e --- /dev/null +++ b/tests/testthat/test-read_cargo_metadata.R @@ -0,0 +1,38 @@ +test_that("read_cargo_metadata() returns crate or workspace metadata", { + skip_if_not_installed("usethis") + + path <- local_package("testpkg") + + # capture setup messages + withr::local_options(usethis.quiet = FALSE) + + use_extendr(path, quiet = TRUE) + + out <- read_cargo_metadata(path) + + expect_type(out, "list") + + expect_equal( + out[["packages"]][["name"]], + "testpkg" + ) + + expect_equal( + out[["packages"]][["version"]], + "0.1.0" + ) + + expect_equal( + out[["packages"]][["dependencies"]][[1]][["name"]], + "extendr-api" + ) + + expect_equal( + out[["workspace_root"]], + normalizePath( + file.path(path, "src", "rust"), + winslash = "\\", + mustWork = FALSE + ) + ) +})