From 71c2dcca45e2c28f0ebd121b89c9db6170f19ac4 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Thu, 15 Feb 2024 23:30:27 -0500 Subject: [PATCH 1/6] vendor path --- R/vendor.R | 46 +++++++++++++++++++++++++++--------- man/cpp_vendor.Rd | 7 +++--- tests/testthat/test-vendor.R | 6 ++--- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/R/vendor.R b/R/vendor.R index 5fe10fe2..ec78ed11 100644 --- a/R/vendor.R +++ b/R/vendor.R @@ -9,13 +9,14 @@ #' cpp11 currently installed on your machine. #' #' If you choose to vendor the headers you should _remove_ `LinkingTo: -#' cpp11` from your DESCRIPTION. +#' cpp11` from your DESCRIPTION. This is done automatically by this function. #' #' **Note**: vendoring places the responsibility of updating the code on #' **you**. Bugfixes and new features in cpp11 will not be available for your #' code until you run `cpp_vendor()` again. #' -#' @inheritParams cpp_register +#' @param path The path to vendor the code into. The default is +#' `./inst/include/`. #' @return The file path to the vendored code (invisibly). #' @export #' @examples @@ -30,13 +31,15 @@ #' #' # cleanup #' unlink(dir, recursive = TRUE) -cpp_vendor <- function(path = ".") { - new <- file.path(path, "inst", "include", "cpp11") +cpp_vendor <- function(path = "./inst/include/") { + new <- file.path(path, "cpp11") if (dir.exists(new)) { stop("'", new, "' already exists\n * run unlink('", new, "', recursive = TRUE)", call. = FALSE) } + # Vendor cpp11 ---- + dir.create(new , recursive = TRUE, showWarnings = FALSE) current <- system.file("include", "cpp11", package = "cpp11") @@ -48,16 +51,37 @@ cpp_vendor <- function(path = ".") { cpp11_header <- sprintf("// cpp11 version: %s\n// vendored on: %s", cpp11_version, Sys.Date()) - files <- list.files(current, full.names = TRUE) + write_header(path, "cpp11.hpp", "cpp11", cpp11_header) + + copy_files(list.files(current, full.names = TRUE), path, "cpp11", cpp11_header) + + # Additional steps to make vendoring work ---- + + message(paste( + "Makevars and/or Makevars.win should have a line such as", + "'PKG_CPPFLAGS = -I../inst/include'" + )) + + message("DESCRIPTION should not have lines such as 'LinkingTo: cpp11'") + + invisible(new) +} +write_header <- function(path, header, pkg, cpp11_header) { writeLines( - c(cpp11_header, readLines(system.file("include", "cpp11.hpp", package = "cpp11"))), - file.path(dirname(new), "cpp11.hpp") + c( + cpp11_header, + readLines(system.file("include", header, package = pkg)) + ), + file.path(path, header) ) +} +copy_files <- function(files, path, out, cpp11_header) { for (f in files) { - writeLines(c(cpp11_header, readLines(f)), file.path(new, basename(f))) + writeLines( + c(cpp11_header, readLines(f)), + file.path(path, out, basename(f)) + ) } - - invisible(new) -} +} \ No newline at end of file diff --git a/man/cpp_vendor.Rd b/man/cpp_vendor.Rd index 857e49cf..d52bf3ba 100644 --- a/man/cpp_vendor.Rd +++ b/man/cpp_vendor.Rd @@ -4,10 +4,11 @@ \alias{cpp_vendor} \title{Vendor the cpp11 dependency} \usage{ -cpp_vendor(path = ".") +cpp_vendor(path = "./inst/include/") } \arguments{ -\item{path}{The path to the package root directory} +\item{path}{The path to vendor the code into. The default is +\verb{./inst/include/}.} } \value{ The file path to the vendored code (invisibly). @@ -22,7 +23,7 @@ headers into the \code{inst/include} folder of your package and adding 'cpp11 version: XYZ' to the top of the files, where XYZ is the version of cpp11 currently installed on your machine. -If you choose to vendor the headers you should \emph{remove} \code{LinkingTo: cpp11} from your DESCRIPTION. +If you choose to vendor the headers you should \emph{remove} \code{LinkingTo: cpp11} from your DESCRIPTION. This is done automatically by this function. \strong{Note}: vendoring places the responsibility of updating the code on \strong{you}. Bugfixes and new features in cpp11 will not be available for your diff --git a/tests/testthat/test-vendor.R b/tests/testthat/test-vendor.R index 361c9ad9..3cf21f8f 100644 --- a/tests/testthat/test-vendor.R +++ b/tests/testthat/test-vendor.R @@ -24,8 +24,8 @@ describe("cpp_vendor", { cpp_vendor(pkg_path(pkg)) - expect_true(dir.exists(file.path(p, "inst", "include", "cpp11"))) - expect_true(file.exists(file.path(p, "inst", "include", "cpp11.hpp"))) - expect_true(file.exists(file.path(p, "inst", "include", "cpp11", "declarations.hpp"))) + expect_true(dir.exists(file.path(p, "cpp11"))) + expect_true(file.exists(file.path(p, "cpp11.hpp"))) + expect_true(file.exists(file.path(p, "cpp11", "declarations.hpp"))) }) }) From 10d3565b9d8f24315ea8db36484fa29cda7823d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mauricio=20=22Pach=C3=A1=22=20Vargas=20Sep=C3=BAlveda?= Date: Sat, 6 Apr 2024 19:58:37 -0400 Subject: [PATCH 2/6] Update tests/testthat/test-vendor.R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kirill Müller --- tests/testthat/test-vendor.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-vendor.R b/tests/testthat/test-vendor.R index 3cf21f8f..658c999f 100644 --- a/tests/testthat/test-vendor.R +++ b/tests/testthat/test-vendor.R @@ -22,7 +22,7 @@ describe("cpp_vendor", { pkg <- local_package() p <- pkg_path(pkg) - cpp_vendor(pkg_path(pkg)) + cpp_vendor(file.path(pkg_path(pkg), "inst/include")) expect_true(dir.exists(file.path(p, "cpp11"))) expect_true(file.exists(file.path(p, "cpp11.hpp"))) From da1c84e573406bced4e6e99950ce75eece2ed309 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Sat, 6 Apr 2024 21:13:06 -0400 Subject: [PATCH 3/6] fix vendor --- R/vendor.R | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/R/vendor.R b/R/vendor.R index ec78ed11..fb3dbf02 100644 --- a/R/vendor.R +++ b/R/vendor.R @@ -32,7 +32,7 @@ #' # cleanup #' unlink(dir, recursive = TRUE) cpp_vendor <- function(path = "./inst/include/") { - new <- file.path(path, "cpp11") + new <- file.path(path) if (dir.exists(new)) { stop("'", new, "' already exists\n * run unlink('", new, "', recursive = TRUE)", call. = FALSE) @@ -40,9 +40,11 @@ cpp_vendor <- function(path = "./inst/include/") { # Vendor cpp11 ---- - dir.create(new , recursive = TRUE, showWarnings = FALSE) + dir.create(new, recursive = TRUE, showWarnings = FALSE) + dir.create(file.path(new, "cpp11"), recursive = TRUE, showWarnings = FALSE) current <- system.file("include", "cpp11", package = "cpp11") + if (!nzchar(current)) { stop("cpp11 is not installed", call. = FALSE) } @@ -51,18 +53,50 @@ cpp_vendor <- function(path = "./inst/include/") { cpp11_header <- sprintf("// cpp11 version: %s\n// vendored on: %s", cpp11_version, Sys.Date()) - write_header(path, "cpp11.hpp", "cpp11", cpp11_header) + main_header <- list.files(current, pattern = "\\.hpp$", full.names = TRUE) + headers <- list.files(file.path(current, "cpp11"), pattern = "\\.hpp$", full.names = TRUE) + + writeLines(c(cpp11_header, readLines(main_header)), file.path(new, basename(main_header))) - copy_files(list.files(current, full.names = TRUE), path, "cpp11", cpp11_header) + for (h in headers) { + writeLines(c(cpp11_header, readLines(h)), file.path(new, "cpp11", basename(h))) + } # Additional steps to make vendoring work ---- - message(paste( - "Makevars and/or Makevars.win should have a line such as", - "'PKG_CPPFLAGS = -I../inst/include'" + message(sprintf( + "Adding PKG_CPPFLAGS = -I../%s to src/Makevars and src/Makevars.win.", + new )) - message("DESCRIPTION should not have lines such as 'LinkingTo: cpp11'") + makevars <- "src/Makevars" + makevars_win <- "src/Makevars.win" + makevars_line <- paste0("PKG_CPPFLAGS = -I ../", new) + + if (file.exists(makevars)) { + if (!any(grepl(paste0("^PKG_CPPFLAGS\\s*=\\s*-I\\s*\\.\\./", new), readLines(makevars)))) { + writeLines(c(readLines(makevars), makevars_line), makevars) + } + } else { + writeLines(makevars_line, makevars) + } + + if (file.exists(makevars_win)) { + if (!any(grepl(paste0("^PKG_CPPFLAGS\\s*=\\s*-I\\s*\\.\\./", new), readLines(makevars_win)))) { + writeLines(c(readLines(makevars_win), makevars_line), makevars_win) + } + } else { + writeLines(makevars_line, makevars_win) + } + + message("Removing 'LinkingTo: cpp11' from DESCRIPTION.") + + desc <- readLines("DESCRIPTION") + desc <- desc[!grepl("^LinkingTo:\\s*cpp11", desc)] + desc <- gsub("^LinkingTo:\\s*cpp11,\\s*", "LinkingTo: ", desc) + desc <- gsub(",\\s*cpp11", "", desc) + + writeLines(descr, "DESCRIPTION") invisible(new) } @@ -84,4 +118,4 @@ copy_files <- function(files, path, out, cpp11_header) { file.path(path, out, basename(f)) ) } -} \ No newline at end of file +} From e2df4307e3b536abeb69f865eba5b2f0c51cda7d Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Tue, 9 Apr 2024 08:59:08 -0400 Subject: [PATCH 4/6] improve DESCRIPTION change with vendoring --- R/vendor.R | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/R/vendor.R b/R/vendor.R index fb3dbf02..4d2e415d 100644 --- a/R/vendor.R +++ b/R/vendor.R @@ -91,10 +91,28 @@ cpp_vendor <- function(path = "./inst/include/") { message("Removing 'LinkingTo: cpp11' from DESCRIPTION.") - desc <- readLines("DESCRIPTION") - desc <- desc[!grepl("^LinkingTo:\\s*cpp11", desc)] - desc <- gsub("^LinkingTo:\\s*cpp11,\\s*", "LinkingTo: ", desc) - desc <- gsub(",\\s*cpp11", "", desc) + descr <- readLines("DESCRIPTION") + linking_to <- which(grepl("^LinkingTo:", descr)) + + if (length(linking_to) > 0) { + linking_to_end <- which(!grepl("^\\s", descr[-(1:linking_to)])) + if (length(linking_to_end) > 0) { + linking_to_end <- linking_to_end[1] + linking_to - 1 + } else { + linking_to_end <- length(descr) + } + linking_to_str <- paste(descr[linking_to:linking_to_end], collapse = "") + linking_to_str <- gsub("\\s+", " ", linking_to_str) + descr[linking_to] <- linking_to_str + descr <- descr[-((linking_to + 1):linking_to_end)] + linking_to_str <- gsub("\\s*cpp11(,|\\s*\\(.*\\))?", "", linking_to_str, perl = TRUE) + linking_to_str <- gsub(",\\s*$", "", linking_to_str) + descr[linking_to] <- linking_to_str + } + + if (grepl("^LinkingTo:\\s*$", descr[linking_to])) { + descr <- descr[-linking_to] + } writeLines(descr, "DESCRIPTION") From 8845015a68b7f0170161f5f46ff61642aec2ea3a Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Mon, 13 May 2024 09:28:57 -0400 Subject: [PATCH 5/6] replace DESC/Make funs with user msg --- R/vendor.R | 67 ++++++++++-------------------------------------------- 1 file changed, 12 insertions(+), 55 deletions(-) diff --git a/R/vendor.R b/R/vendor.R index 4d2e415d..2f4048f3 100644 --- a/R/vendor.R +++ b/R/vendor.R @@ -8,15 +8,11 @@ #' 'cpp11 version: XYZ' to the top of the files, where XYZ is the version of #' cpp11 currently installed on your machine. #' -#' If you choose to vendor the headers you should _remove_ `LinkingTo: -#' cpp11` from your DESCRIPTION. This is done automatically by this function. -#' #' **Note**: vendoring places the responsibility of updating the code on #' **you**. Bugfixes and new features in cpp11 will not be available for your #' code until you run `cpp_vendor()` again. #' -#' @param path The path to vendor the code into. The default is -#' `./inst/include/`. +#' @param path The path to vendor the code into. #' @return The file path to the vendored code (invisibly). #' @export #' @examples @@ -31,7 +27,13 @@ #' #' # cleanup #' unlink(dir, recursive = TRUE) -cpp_vendor <- function(path = "./inst/include/") { +cpp_vendor <- function(path = NULL) { + if (is.null(path)) { + stop("You must provide a path to vendor the code into", call. = FALSE) + } else { + path <- paste0(path, "/inst/include") + } + new <- file.path(path) if (dir.exists(new)) { @@ -64,57 +66,12 @@ cpp_vendor <- function(path = "./inst/include/") { # Additional steps to make vendoring work ---- - message(sprintf( - "Adding PKG_CPPFLAGS = -I../%s to src/Makevars and src/Makevars.win.", - new + message(paste( + "Makevars and/or Makevars.win should have a line such as", + "'PKG_CPPFLAGS = -I../inst/include'" )) - makevars <- "src/Makevars" - makevars_win <- "src/Makevars.win" - makevars_line <- paste0("PKG_CPPFLAGS = -I ../", new) - - if (file.exists(makevars)) { - if (!any(grepl(paste0("^PKG_CPPFLAGS\\s*=\\s*-I\\s*\\.\\./", new), readLines(makevars)))) { - writeLines(c(readLines(makevars), makevars_line), makevars) - } - } else { - writeLines(makevars_line, makevars) - } - - if (file.exists(makevars_win)) { - if (!any(grepl(paste0("^PKG_CPPFLAGS\\s*=\\s*-I\\s*\\.\\./", new), readLines(makevars_win)))) { - writeLines(c(readLines(makevars_win), makevars_line), makevars_win) - } - } else { - writeLines(makevars_line, makevars_win) - } - - message("Removing 'LinkingTo: cpp11' from DESCRIPTION.") - - descr <- readLines("DESCRIPTION") - linking_to <- which(grepl("^LinkingTo:", descr)) - - if (length(linking_to) > 0) { - linking_to_end <- which(!grepl("^\\s", descr[-(1:linking_to)])) - if (length(linking_to_end) > 0) { - linking_to_end <- linking_to_end[1] + linking_to - 1 - } else { - linking_to_end <- length(descr) - } - linking_to_str <- paste(descr[linking_to:linking_to_end], collapse = "") - linking_to_str <- gsub("\\s+", " ", linking_to_str) - descr[linking_to] <- linking_to_str - descr <- descr[-((linking_to + 1):linking_to_end)] - linking_to_str <- gsub("\\s*cpp11(,|\\s*\\(.*\\))?", "", linking_to_str, perl = TRUE) - linking_to_str <- gsub(",\\s*$", "", linking_to_str) - descr[linking_to] <- linking_to_str - } - - if (grepl("^LinkingTo:\\s*$", descr[linking_to])) { - descr <- descr[-linking_to] - } - - writeLines(descr, "DESCRIPTION") + message("DESCRIPTION should not have lines such as 'LinkingTo: cpp11'") invisible(new) } From 6778095e23fdaf5b25442289dd52383b56d32e9a Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Mon, 13 May 2024 11:06:26 -0400 Subject: [PATCH 6/6] fix eventual CRAN warning --- DESCRIPTION | 2 +- R/vendor.R | 68 ++++++++++++++++++++++-------------- man/cpp_vendor.Rd | 9 +++-- tests/testthat/test-vendor.R | 8 ++--- 4 files changed, 50 insertions(+), 37 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5f69870b..e312ad37 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -55,4 +55,4 @@ Config/Needs/cpp11/cpp_register: vctrs Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 diff --git a/R/vendor.R b/R/vendor.R index 2f4048f3..a7e40fbb 100644 --- a/R/vendor.R +++ b/R/vendor.R @@ -12,7 +12,8 @@ #' **you**. Bugfixes and new features in cpp11 will not be available for your #' code until you run `cpp_vendor()` again. #' -#' @param path The path to vendor the code into. +#' @param dir The directoyy to vendor the code into. +#' @param subdir The subdirectory to vendor the code into. #' @return The file path to the vendored code (invisibly). #' @export #' @examples @@ -27,42 +28,53 @@ #' #' # cleanup #' unlink(dir, recursive = TRUE) -cpp_vendor <- function(path = NULL) { - if (is.null(path)) { +cpp_vendor <- function(dir = NULL, subdir = "/inst/include") { + if (is.null(dir)) { stop("You must provide a path to vendor the code into", call. = FALSE) - } else { - path <- paste0(path, "/inst/include") } - - new <- file.path(path) - if (dir.exists(new)) { - stop("'", new, "' already exists\n * run unlink('", new, "', recursive = TRUE)", call. = FALSE) + path <- paste0(dir, subdir) + + path2 <- file.path(path, "cpp11") + if (dir.exists(path2)) { + stop("'", path2, "' already exists\n * run unlink('", path2, "', recursive = TRUE)", call. = FALSE) } # Vendor cpp11 ---- - dir.create(new, recursive = TRUE, showWarnings = FALSE) - dir.create(file.path(new, "cpp11"), recursive = TRUE, showWarnings = FALSE) + dir.create( + path2, + recursive = TRUE, + showWarnings = FALSE + ) - current <- system.file("include", "cpp11", package = "cpp11") + current_cpp11 <- system.file( + "include", + "cpp11", + package = "cpp11" + ) - if (!nzchar(current)) { + if (!nzchar(current_cpp11)) { stop("cpp11 is not installed", call. = FALSE) } cpp11_version <- utils::packageVersion("cpp11") - cpp11_header <- sprintf("// cpp11 version: %s\n// vendored on: %s", cpp11_version, Sys.Date()) - - main_header <- list.files(current, pattern = "\\.hpp$", full.names = TRUE) - headers <- list.files(file.path(current, "cpp11"), pattern = "\\.hpp$", full.names = TRUE) + cpp11_header <- sprintf( + "// cpp11 version: %s\n// vendored on: %s", + cpp11_version, + Sys.Date() + ) - writeLines(c(cpp11_header, readLines(main_header)), file.path(new, basename(main_header))) + write_header( + path, "cpp11.hpp", "cpp11", + cpp11_header + ) - for (h in headers) { - writeLines(c(cpp11_header, readLines(h)), file.path(new, "cpp11", basename(h))) - } + copy_files( + list.files(current_cpp11, full.names = TRUE), + path, "cpp11", cpp11_header + ) # Additional steps to make vendoring work ---- @@ -73,23 +85,25 @@ cpp_vendor <- function(path = NULL) { message("DESCRIPTION should not have lines such as 'LinkingTo: cpp11'") - invisible(new) + invisible(path) } -write_header <- function(path, header, pkg, cpp11_header) { +write_header <- function(path, header, pkg, cpp11armadillo_header) { writeLines( c( - cpp11_header, - readLines(system.file("include", header, package = pkg)) + cpp11armadillo_header, + readLines( + system.file("include", header, package = pkg) + ) ), file.path(path, header) ) } -copy_files <- function(files, path, out, cpp11_header) { +copy_files <- function(files, path, out, cpp11armadillo_header) { for (f in files) { writeLines( - c(cpp11_header, readLines(f)), + c(cpp11armadillo_header, readLines(f)), file.path(path, out, basename(f)) ) } diff --git a/man/cpp_vendor.Rd b/man/cpp_vendor.Rd index d52bf3ba..0fd75e0a 100644 --- a/man/cpp_vendor.Rd +++ b/man/cpp_vendor.Rd @@ -4,11 +4,12 @@ \alias{cpp_vendor} \title{Vendor the cpp11 dependency} \usage{ -cpp_vendor(path = "./inst/include/") +cpp_vendor(dir = NULL, subdir = "/inst/include") } \arguments{ -\item{path}{The path to vendor the code into. The default is -\verb{./inst/include/}.} +\item{dir}{The directoyy to vendor the code into.} + +\item{subdir}{The subdirectory to vendor the code into.} } \value{ The file path to the vendored code (invisibly). @@ -23,8 +24,6 @@ headers into the \code{inst/include} folder of your package and adding 'cpp11 version: XYZ' to the top of the files, where XYZ is the version of cpp11 currently installed on your machine. -If you choose to vendor the headers you should \emph{remove} \code{LinkingTo: cpp11} from your DESCRIPTION. This is done automatically by this function. - \strong{Note}: vendoring places the responsibility of updating the code on \strong{you}. Bugfixes and new features in cpp11 will not be available for your code until you run \code{cpp_vendor()} again. diff --git a/tests/testthat/test-vendor.R b/tests/testthat/test-vendor.R index 658c999f..361c9ad9 100644 --- a/tests/testthat/test-vendor.R +++ b/tests/testthat/test-vendor.R @@ -22,10 +22,10 @@ describe("cpp_vendor", { pkg <- local_package() p <- pkg_path(pkg) - cpp_vendor(file.path(pkg_path(pkg), "inst/include")) + cpp_vendor(pkg_path(pkg)) - expect_true(dir.exists(file.path(p, "cpp11"))) - expect_true(file.exists(file.path(p, "cpp11.hpp"))) - expect_true(file.exists(file.path(p, "cpp11", "declarations.hpp"))) + expect_true(dir.exists(file.path(p, "inst", "include", "cpp11"))) + expect_true(file.exists(file.path(p, "inst", "include", "cpp11.hpp"))) + expect_true(file.exists(file.path(p, "inst", "include", "cpp11", "declarations.hpp"))) }) })