R/license_note.R

Defines functions write_license_note

Documented in write_license_note

#' Generate LICENSE.note file.
#'
#' LICENSE.note generated by this function contains information about Rust crate dependencies.
#' To use this function, the [cargo-lincense](https://crates.io/crates/cargo-license) command must be installed.
#' @param force Logical indicating whether to regenerate LICENSE.note if LICENSE.note already exists.
#' @inheritParams register_extendr
#' @return No return value, called for side effects.
#' @export
write_license_note <- function(path = ".", quiet = FALSE, force = TRUE) {
  if (!cargo_command_available(c("license", "--help"))) {
    cli::cli_abort(
      c(
        "The {.code cargo license} command is required to run the {.fun write_license_note} function.",
        "*" = "Please install cargo-license ({.url https://crates.io/crates/cargo-license}) first.",
        i = "Run {.code cargo install cargo-license} from your terminal."
      ),
      class = "rextendr_error"
    )
  }

  manifest_file <- rprojroot::find_package_root_file("src", "rust", "Cargo.toml", path = path)
  outfile <- rprojroot::find_package_root_file("LICENSE.note", path = path)

  if (!isTRUE(force) && file.exists(outfile)) {
    cli::cli_abort(
      c(
        "LICENSE.note already exists.",
        "If you want to regenerate LICENSE.note, set `force = TRUE` to {.fun write_license_note}."
      ),
      class = "rextendr_error"
    )
  }

  list_license <- processx::run(
    "cargo",
    c(
      "license",
      "--authors",
      "--json",
      "--avoid-build-deps",
      "--avoid-dev-deps",
      "--manifest-path", manifest_file
    )
  )$stdout %>%
    jsonlite::parse_json()

  package_names <- processx::run(
    "cargo",
    c(
      "metadata",
      "--no-deps",
      "--format-version", "1",
      "--manifest-path", manifest_file
    )
  )$stdout %>%
    jsonlite::parse_json() %>%
    purrr::pluck("packages") %>%
    purrr::map_chr("name")

  .prep_authors <- function(authors, package) {
    ifelse(!is.null(authors), authors, paste0(package, " authors")) %>%
      stringi::stri_replace_all_regex(r"(\ <.+?>)", "") %>%
      stringi::stri_replace_all_regex(r"(\|)", ", ")
  }

  separator <- "-------------------------------------------------------------"

  note_header <- paste0(
    "The binary compiled from the source code of this package contains the following Rust crates:\n",
    "\n",
    "\n",
    separator
  )

  note_body <- list_license %>%
    purrr::discard(function(x) x$name %in% package_names) %>%
    purrr::map_chr(
      function(x) {
        paste0(
          "\n",
          "Name:        ", x$name, "\n",
          "Repository:  ", x$repository, "\n",
          "Authors:     ", .prep_authors(x$authors, x$name), "\n",
          "License:     ", x$license, "\n",
          "\n",
          separator
        )
      }
    )

  write_file(
    text = c(note_header, note_body),
    path = outfile,
    search_root_from = path,
    quiet = quiet
  )
}
extendr/rextendr documentation built on April 4, 2024, 3:03 a.m.