From 4df42789387e9e8450cfd605fe46400c2cd09027 Mon Sep 17 00:00:00 2001 From: Drew Herren Date: Fri, 21 Nov 2025 01:00:12 -0600 Subject: [PATCH 1/3] CRAN submission prep --- DESCRIPTION | 2 +- cleanup | 2 + cran-bootstrap.R | 662 +++++++++++++++++++++++++++++------------------ 3 files changed, 413 insertions(+), 253 deletions(-) create mode 100755 cleanup diff --git a/DESCRIPTION b/DESCRIPTION index 6a95bb9d..c83f1e2b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: stochtree Title: Stochastic Tree Ensembles (XBART and BART) for Supervised Learning and Causal Inference -Version: 0.1.1 +Version: 0.2.0 Authors@R: c( person("Drew", "Herren", email = "drewherrenopensource@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-4109-6611")), diff --git a/cleanup b/cleanup new file mode 100755 index 00000000..8ff2b067 --- /dev/null +++ b/cleanup @@ -0,0 +1,2 @@ +#!/bin/sh +rm -f src/Makevars \ No newline at end of file diff --git a/cran-bootstrap.R b/cran-bootstrap.R index 0e865877..00ec6081 100644 --- a/cran-bootstrap.R +++ b/cran-bootstrap.R @@ -1,86 +1,109 @@ # Derived from a combination of -# +# # 1) The bootstrap.R files in the arrow-adbc suite of R packages, # https://github.com/apache/arrow-adbc/tree/main/r, all of which are Apache # licensed with the following copyright: # Copyright 2022 The Apache Software Foundation -# -# 2) LightGBM's build-cran-package.sh script, -# https://github.com/microsoft/LightGBM/blob/master/build-cran-package.sh, +# +# 2) LightGBM's build-cran-package.sh script, +# https://github.com/microsoft/LightGBM/blob/master/build-cran-package.sh, # which is MIT licensed with the following copyright: # Copyright (c) Microsoft Corporation -# -# Includes two command line arguments: +# +# Includes three command line arguments: # include_vignettes : 1 to include the vignettes folder in the R package subfolder # 0 to exclude vignettes (overriden to 1 if pkgdown_build = 1 below) -# +# # pkgdown_build : 1 to include pkgdown specific files (R_README.md, _pkgdown.yml) # 0 to exclude pkgdown specific files -# +# # include_tests : 1 to include unit tests # 0 to exclude unit tests -# +# # Run this script from the command line via -# +# # Explicitly include vignettes and unit tests and build pkgdown site # ------------------------------------------------------------------ # Rscript cran-bootstrap.R 1 1 1 -# +# # Explicitly include vignettes and unit tests but don't build pkgdown site # ------------------------------------------------------------------------ # Rscript cran-bootstrap.R 1 0 1 -# +# # Explicitly exclude vignettes and unit tests and don't build pkgdown site # ------------------------------------------------------------------------ # Rscript cran-bootstrap.R 0 0 0 -# +# # Exclude vignettes, unit tests, and pkgdown by default # ----------------------------------------------------- # Rscript cran-bootstrap.R +# +# For CRAN preparation, please run: +# ----------------------------------------------------- +# Rscript cran-bootstrap.R 0 0 1 # Unpack command line arguments args <- commandArgs(trailingOnly = T) -if (length(args) > 0){ - include_vignettes <- as.logical(as.integer(args[1])) - pkgdown_build <- as.logical(as.integer(args[2])) - include_tests <- as.logical(as.integer(args[3])) -} else{ - include_vignettes <- F - pkgdown_build <- F - include_tests <- F +if (length(args) > 0) { + include_vignettes <- as.logical(as.integer(args[1])) + pkgdown_build <- as.logical(as.integer(args[2])) + include_tests <- as.logical(as.integer(args[3])) +} else { + include_vignettes <- F + pkgdown_build <- F + include_tests <- F } # Create the stochtree_cran folder cran_dir <- "stochtree_cran" if (!dir.exists(cran_dir)) { - dir.create(cran_dir, recursive = TRUE) + dir.create(cran_dir, recursive = TRUE) } # Copy the "core" package files to CRAN folder -src_files <- list.files("src", pattern = ".[^o]$", recursive = TRUE, full.names = TRUE) -pybind_src_files <- list.files("src", pattern = "^(py_)", recursive = TRUE, full.names = TRUE) +src_files <- list.files( + "src", + pattern = ".[^o]$", + recursive = TRUE, + full.names = TRUE +) +pybind_src_files <- list.files( + "src", + pattern = "^(py_)", + recursive = TRUE, + full.names = TRUE +) r_src_files <- src_files[!(src_files %in% pybind_src_files)] -r_src_files <- r_src_files[!(r_src_files %in% c("src/Makevars", "src/Makevars.win"))] +r_src_files <- r_src_files[ + !(r_src_files %in% c("src/Makevars", "src/Makevars.win")) +] cat(r_src_files) pkg_core_files <- c( - ".Rbuildignore", - "configure", - "configure.ac", - "configure.win", - "cran-comments.md", - "DESCRIPTION", - "inst/COPYRIGHTS", - "LICENSE", - list.files("man", recursive = TRUE, full.names = TRUE), - "NAMESPACE", - "NEWS.md", - list.files("R", recursive = TRUE, full.names = TRUE), - r_src_files + ".Rbuildignore", + "cleanup", + "configure", + "configure.ac", + "configure.win", + "cran-comments.md", + "DESCRIPTION", + "inst/COPYRIGHTS", + "LICENSE", + list.files("man", recursive = TRUE, full.names = TRUE), + "NAMESPACE", + "NEWS.md", + list.files("R", recursive = TRUE, full.names = TRUE), + r_src_files ) if (include_vignettes) { - pkg_core_files <- c( - pkg_core_files, list.files("vignettes", pattern = ".(Rmd|bib)$", recursive = TRUE, full.names = TRUE) - ) + pkg_core_files <- c( + pkg_core_files, + list.files( + "vignettes", + pattern = ".(Rmd|bib)$", + recursive = TRUE, + full.names = TRUE + ) + ) } pkg_core_files_dst <- file.path(cran_dir, pkg_core_files) @@ -88,115 +111,141 @@ pkg_core_files_dst <- file.path(cran_dir, pkg_core_files) readme_file_src <- file.path("R_README.md") readme_file_dst <- file.path(cran_dir, c("README.md")) if (file.copy(readme_file_src, readme_file_dst)) { - cat("Copied R README.md to CRAN subdirectory\n") + cat("Copied R README.md to CRAN subdirectory\n") } else { - stop("Failed to copy R README.md") + stop("Failed to copy R README.md") } # Copy _pkgdown.yml if requested if (pkgdown_build) { - pkgdown_yml_src <- file.path("_pkgdown.yml") - pkgdown_yml_dst <- file.path(cran_dir, c("_pkgdown.yml")) - if (file.copy(pkgdown_yml_src, pkgdown_yml_dst)) { - cat("Copied _pkgdown.yml to CRAN subdirectory\n") - } else { - stop("Failed to copy _pkgdown.yml") - } + pkgdown_yml_src <- file.path("_pkgdown.yml") + pkgdown_yml_dst <- file.path(cran_dir, c("_pkgdown.yml")) + if (file.copy(pkgdown_yml_src, pkgdown_yml_dst)) { + cat("Copied _pkgdown.yml to CRAN subdirectory\n") + } else { + stop("Failed to copy _pkgdown.yml") + } } # Handle tests separately (move from test/R/ folder to tests/ folder) if (include_tests) { - test_files_src <- list.files("test/R", recursive = TRUE, full.names = TRUE) - test_files_dst <- file.path(cran_dir, gsub("test/R", "tests", test_files_src)) - pkg_core_files <- c(pkg_core_files, test_files_src) - pkg_core_files_dst <- c(pkg_core_files_dst, test_files_dst) + test_files_src <- list.files("test/R", recursive = TRUE, full.names = TRUE) + test_files_dst <- file.path(cran_dir, gsub("test/R", "tests", test_files_src)) + pkg_core_files <- c(pkg_core_files, test_files_src) + pkg_core_files_dst <- c(pkg_core_files_dst, test_files_dst) } # Copy over all core package files if (all(file.exists(pkg_core_files))) { - n_removed <- suppressWarnings(sum(file.remove(pkg_core_files_dst))) - if (n_removed > 0) { - cat(sprintf("Removed %d previously vendored files from temporary CRAN directory (%s)\n", n_removed, cran_dir)) - } - - cat( - sprintf( - "Copying core package files to CRAN subdirectory\n" - ) + n_removed <- suppressWarnings(sum(file.remove(pkg_core_files_dst))) + if (n_removed > 0) { + cat(sprintf( + "Removed %d previously vendored files from temporary CRAN directory (%s)\n", + n_removed, + cran_dir + )) + } + + cat( + sprintf( + "Copying core package files to CRAN subdirectory\n" ) - - # Recreate the directory structure - dst_dirs <- unique(dirname(pkg_core_files_dst)) - for (dst_dir in dst_dirs) { - if (!dir.exists(dst_dir)) { - dir.create(dst_dir, recursive = TRUE) - } - } - - if (all(file.copy(pkg_core_files, pkg_core_files_dst))) { - cat("All core package files successfully copied to CRAN subdirectory\n") - } else { - stop("Failed to copy all core package files") + ) + + # Recreate the directory structure + dst_dirs <- unique(dirname(pkg_core_files_dst)) + for (dst_dir in dst_dirs) { + if (!dir.exists(dst_dir)) { + dir.create(dst_dir, recursive = TRUE) } + } + + if (all(file.copy(pkg_core_files, pkg_core_files_dst))) { + cat("All core package files successfully copied to CRAN subdirectory\n") + } else { + stop("Failed to copy all core package files") + } } # Overwrite PKG_CPPFLAGS in src/Makevars.in cran_makevars <- file.path(cran_dir, "src/Makevars.in") makevars_lines <- readLines(cran_makevars) -makevars_lines[grep(" -I$(PKGROOT)/include \\", makevars_lines, fixed = T)] <- " -I$(PKGROOT)/src/include \\" -makevars_lines <- makevars_lines[-c( - grep(" -I$(PKGROOT)/deps/eigen \\", makevars_lines, fixed = T), - grep(" -I$(PKGROOT)/deps/fmt/include \\", makevars_lines, fixed = T), - grep(" -I$(PKGROOT)/deps/fast_double_parser/include \\", makevars_lines, fixed = T) -)] +makevars_lines[grep( + " -I$(PKGROOT)/include \\", + makevars_lines, + fixed = T +)] <- " -I$(PKGROOT)/src/include \\" +makevars_lines <- makevars_lines[ + -c( + grep(" -I$(PKGROOT)/deps/eigen \\", makevars_lines, fixed = T), + grep(" -I$(PKGROOT)/deps/fmt/include \\", makevars_lines, fixed = T), + grep( + " -I$(PKGROOT)/deps/fast_double_parser/include \\", + makevars_lines, + fixed = T + ) + ) +] writeLines(makevars_lines, cran_makevars) # Overwrite PKG_CPPFLAGS in src/Makevars.win.in cran_makevars_win <- file.path(cran_dir, "src/Makevars.win.in") makevars_win_lines <- readLines(cran_makevars_win) -makevars_win_lines[grep(" -I$(PKGROOT)/include \\", makevars_win_lines, fixed = T)] <- " -I$(PKGROOT)/src/include \\" -makevars_win_lines <- makevars_win_lines[-c( - grep(" -I$(PKGROOT)/deps/eigen \\", makevars_win_lines, fixed = T), - grep(" -I$(PKGROOT)/deps/fmt/include \\", makevars_win_lines, fixed = T), - grep(" -I$(PKGROOT)/deps/fast_double_parser/include \\", makevars_win_lines, fixed = T) -)] +makevars_win_lines[grep( + " -I$(PKGROOT)/include \\", + makevars_win_lines, + fixed = T +)] <- " -I$(PKGROOT)/src/include \\" +makevars_win_lines <- makevars_win_lines[ + -c( + grep(" -I$(PKGROOT)/deps/eigen \\", makevars_win_lines, fixed = T), + grep(" -I$(PKGROOT)/deps/fmt/include \\", makevars_win_lines, fixed = T), + grep( + " -I$(PKGROOT)/deps/fast_double_parser/include \\", + makevars_win_lines, + fixed = T + ) + ) +] writeLines(makevars_win_lines, cran_makevars_win) # Remove vignette deps from DESCRIPTION if no vignettes if (!include_vignettes) { - cran_description <- file.path(cran_dir, "DESCRIPTION") - description_lines <- readLines(cran_description) - suggestion_begin <- grep("Suggests:", description_lines) + 2 - suggestion_end <- grep("VignetteBuilder:", description_lines) - description_lines <- description_lines[-(suggestion_begin:suggestion_end)] - writeLines(description_lines, cran_description) + cran_description <- file.path(cran_dir, "DESCRIPTION") + description_lines <- readLines(cran_description) + suggestion_begin <- grep("Suggests:", description_lines) + 2 + suggestion_end <- grep("VignetteBuilder:", description_lines) + description_lines <- description_lines[-(suggestion_begin:suggestion_end)] + writeLines(description_lines, cran_description) } # Remove testthat deps from DESCRIPTION if no tests if (!include_tests) { - cran_description <- file.path(cran_dir, "DESCRIPTION") - description_lines <- readLines(cran_description) - if (include_vignettes) { - suggestion_match <- grep("testthat (>= 3.0.0)", description_lines) - suggestion_lines <- suggestion_match - } else { - suggestion_begin <- grep("Suggests:", description_lines) - suggestion_end <- grep("SystemRequirements:", description_lines) - 1 - suggestion_lines <- suggestion_begin:suggestion_end - } - testthat_config_line <- grep("Config/testthat/edition:", description_lines) - description_lines <- description_lines[-c(suggestion_lines, testthat_config_line)] - writeLines(description_lines, cran_description) + cran_description <- file.path(cran_dir, "DESCRIPTION") + description_lines <- readLines(cran_description) + if (include_vignettes) { + suggestion_match <- grep("testthat (>= 3.0.0)", description_lines) + suggestion_lines <- suggestion_match + } else { + suggestion_begin <- grep("Suggests:", description_lines) + suggestion_end <- grep("SystemRequirements:", description_lines) - 1 + suggestion_lines <- suggestion_begin:suggestion_end + } + testthat_config_line <- grep("Config/testthat/edition:", description_lines) + description_lines <- description_lines[ + -c(suggestion_lines, testthat_config_line) + ] + writeLines(description_lines, cran_description) } # Remove vignettes from _pkgdown.yml if no vignettes if ((!include_vignettes) & (pkgdown_build)) { - pkgdown_yml <- file.path(cran_dir, "_pkgdown.yml") - pkgdown_yml_lines <- readLines(pkgdown_yml) - articles_begin <- grep("articles:", pkgdown_yml_lines) - articles_end <- length(pkgdown_yml_lines) - pkgdown_yml_lines <- pkgdown_yml_lines[-(articles_begin:articles_end)] - writeLines(pkgdown_yml_lines, pkgdown_yml) + pkgdown_yml <- file.path(cran_dir, "_pkgdown.yml") + pkgdown_yml_lines <- readLines(pkgdown_yml) + articles_begin <- grep("articles:", pkgdown_yml_lines) + articles_end <- length(pkgdown_yml_lines) + pkgdown_yml_lines <- pkgdown_yml_lines[-(articles_begin:articles_end)] + writeLines(pkgdown_yml_lines, pkgdown_yml) } # Copy fast_double_parser header to an include/ subdirectory of src/ @@ -204,43 +253,50 @@ header_folders <- c("nlohmann", "stochtree") header_files_to_vendor_src <- c() header_files_to_vendor_dst <- c() for (header_folder in header_folders) { - # Existing source files - header_subfolder_src <- paste0("include/", header_folder) - header_filenames_src <- list.files(header_subfolder_src, recursive = TRUE) - header_src <- file.path(header_subfolder_src, header_filenames_src) - header_files_to_vendor_src <- c(header_files_to_vendor_src, header_src) - - # Destination files - header_subfolder_dst <- paste0(cran_dir, "/src/include/", header_folder) - header_dst <- file.path(header_subfolder_dst, basename(header_src)) - header_files_to_vendor_dst <- c(header_files_to_vendor_dst, header_dst) + # Existing source files + header_subfolder_src <- paste0("include/", header_folder) + header_filenames_src <- list.files(header_subfolder_src, recursive = TRUE) + header_src <- file.path(header_subfolder_src, header_filenames_src) + header_files_to_vendor_src <- c(header_files_to_vendor_src, header_src) + + # Destination files + header_subfolder_dst <- paste0(cran_dir, "/src/include/", header_folder) + header_dst <- file.path(header_subfolder_dst, basename(header_src)) + header_files_to_vendor_dst <- c(header_files_to_vendor_dst, header_dst) } -fast_double_parser_src <- file.path("deps/fast_double_parser/include/fast_double_parser.h") -fast_double_parser_dst <- file.path(cran_dir, "src/include/fast_double_parser.h") +fast_double_parser_src <- file.path( + "deps/fast_double_parser/include/fast_double_parser.h" +) +fast_double_parser_dst <- file.path( + cran_dir, + "src/include/fast_double_parser.h" +) if (file.exists(fast_double_parser_src)) { - file_removed <- suppressWarnings(sum(file.remove(fast_double_parser_dst)) > 0) - if (file_removed) { - cat(sprintf("Removed previously vendored fast_double_parser.h file from src/include\n")) - } - - cat( - sprintf( - "Vendoring fast_double_parser.h file from deps/fast_double_parser/include to src/include\n" - ) + file_removed <- suppressWarnings(sum(file.remove(fast_double_parser_dst)) > 0) + if (file_removed) { + cat(sprintf( + "Removed previously vendored fast_double_parser.h file from src/include\n" + )) + } + + cat( + sprintf( + "Vendoring fast_double_parser.h file from deps/fast_double_parser/include to src/include\n" ) - - # Recreate the directory structure - dst_dir <- dirname(fast_double_parser_dst) - if (!dir.exists(dst_dir)) { - dir.create(dst_dir, recursive = TRUE) - } + ) - if (file.copy(fast_double_parser_src, fast_double_parser_dst)) { - cat("fast_double_parser.h header file successfully copied to src/include\n") - } else { - stop("Failed to vendor fast_double_parser.h header file") - } + # Recreate the directory structure + dst_dir <- dirname(fast_double_parser_dst) + if (!dir.exists(dst_dir)) { + dir.create(dst_dir, recursive = TRUE) + } + + if (file.copy(fast_double_parser_src, fast_double_parser_dst)) { + cat("fast_double_parser.h header file successfully copied to src/include\n") + } else { + stop("Failed to vendor fast_double_parser.h header file") + } } # Copy include/ headers to an include/ subdirectory of src/ @@ -248,43 +304,46 @@ header_folders <- c("nlohmann", "stochtree") header_files_to_vendor_src <- c() header_files_to_vendor_dst <- c() for (header_folder in header_folders) { - # Existing source files - header_subfolder_src <- paste0("include/", header_folder) - header_filenames_src <- list.files(header_subfolder_src, recursive = TRUE) - header_src <- file.path(header_subfolder_src, header_filenames_src) - header_files_to_vendor_src <- c(header_files_to_vendor_src, header_src) - - # Destination files - header_subfolder_dst <- paste0(cran_dir, "/src/include/", header_folder) - header_dst <- file.path(header_subfolder_dst, basename(header_src)) - header_files_to_vendor_dst <- c(header_files_to_vendor_dst, header_dst) + # Existing source files + header_subfolder_src <- paste0("include/", header_folder) + header_filenames_src <- list.files(header_subfolder_src, recursive = TRUE) + header_src <- file.path(header_subfolder_src, header_filenames_src) + header_files_to_vendor_src <- c(header_files_to_vendor_src, header_src) + + # Destination files + header_subfolder_dst <- paste0(cran_dir, "/src/include/", header_folder) + header_dst <- file.path(header_subfolder_dst, basename(header_src)) + header_files_to_vendor_dst <- c(header_files_to_vendor_dst, header_dst) } if (all(file.exists(header_files_to_vendor_src))) { - n_removed <- suppressWarnings(sum(file.remove(header_files_to_vendor_dst))) - if (n_removed > 0) { - cat(sprintf("Removed %d previously vendored files from src/include\n", n_removed)) - } - - cat( - sprintf( - "Vendoring files from include/ to src/include\n" - ) + n_removed <- suppressWarnings(sum(file.remove(header_files_to_vendor_dst))) + if (n_removed > 0) { + cat(sprintf( + "Removed %d previously vendored files from src/include\n", + n_removed + )) + } + + cat( + sprintf( + "Vendoring files from include/ to src/include\n" ) - - # Recreate the directory structure - dst_dirs <- unique(dirname(header_files_to_vendor_dst)) - for (dst_dir in dst_dirs) { - if (!dir.exists(dst_dir)) { - dir.create(dst_dir, recursive = TRUE) - } - } - - if (all(file.copy(header_files_to_vendor_src, header_files_to_vendor_dst))) { - cat("All include/ header files successfully copied to src/include\n") - } else { - stop("Failed to vendor all include/ header files") + ) + + # Recreate the directory structure + dst_dirs <- unique(dirname(header_files_to_vendor_dst)) + for (dst_dir in dst_dirs) { + if (!dir.exists(dst_dir)) { + dir.create(dst_dir, recursive = TRUE) } + } + + if (all(file.copy(header_files_to_vendor_src, header_files_to_vendor_dst))) { + cat("All include/ header files successfully copied to src/include\n") + } else { + stop("Failed to vendor all include/ header files") + } } # Copy fmt headers to an include/ subdirectory of src/ @@ -292,104 +351,203 @@ fmt_header_files_to_vendor_src <- c() fmt_header_files_to_vendor_dst <- c() # Existing source files fmt_header_subfolder_src <- "deps/fmt/include/fmt" -fmt_header_filenames_src <- list.files(fmt_header_subfolder_src, pattern = "\\.(h)$", recursive = TRUE) -fmt_header_files_to_vendor_src <- file.path(fmt_header_subfolder_src, fmt_header_filenames_src) +fmt_header_filenames_src <- list.files( + fmt_header_subfolder_src, + pattern = "\\.(h)$", + recursive = TRUE +) +fmt_header_files_to_vendor_src <- file.path( + fmt_header_subfolder_src, + fmt_header_filenames_src +) # Destination files fmt_header_subfolder_dst <- "src/include/fmt" -fmt_header_files_to_vendor_dst <- file.path(cran_dir, fmt_header_subfolder_dst, basename(fmt_header_filenames_src)) +fmt_header_files_to_vendor_dst <- file.path( + cran_dir, + fmt_header_subfolder_dst, + basename(fmt_header_filenames_src) +) if (all(file.exists(fmt_header_files_to_vendor_src))) { - n_removed <- suppressWarnings(sum(file.remove(fmt_header_files_to_vendor_dst))) - if (n_removed > 0) { - cat(sprintf("Removed %d previously vendored files from src/include/fmt\n", n_removed)) + n_removed <- suppressWarnings(sum(file.remove( + fmt_header_files_to_vendor_dst + ))) + if (n_removed > 0) { + cat(sprintf( + "Removed %d previously vendored files from src/include/fmt\n", + n_removed + )) + } + + cat( + sprintf( + "Vendoring files from deps/fmt/include/ to src/include/fmt\n" + ) + ) + + # Recreate the directory structure + dst_dirs <- unique(dirname(fmt_header_files_to_vendor_dst)) + for (dst_dir in dst_dirs) { + if (!dir.exists(dst_dir)) { + dir.create(dst_dir, recursive = TRUE) } - + } + + if ( + all(file.copy( + fmt_header_files_to_vendor_src, + fmt_header_files_to_vendor_dst + )) + ) { cat( - sprintf( - "Vendoring files from deps/fmt/include/ to src/include/fmt\n" - ) + "All deps/fmt/include/ header files successfully copied to src/include/fmt\n" ) - - # Recreate the directory structure - dst_dirs <- unique(dirname(fmt_header_files_to_vendor_dst)) - for (dst_dir in dst_dirs) { - if (!dir.exists(dst_dir)) { - dir.create(dst_dir, recursive = TRUE) - } - } - - if (all(file.copy(fmt_header_files_to_vendor_src, fmt_header_files_to_vendor_dst))) { - cat("All deps/fmt/include/ header files successfully copied to src/include/fmt\n") - } else { - stop("Failed to vendor all deps/fmt/include/ header files") - } + } else { + stop("Failed to vendor all deps/fmt/include/ header files") + } } # Copy Eigen module headers to an include/Eigen subdirectory of src/ -eigen_modules <- c("Cholesky", "Core", "Dense", "Eigenvalues", "Geometry", "Householder", "IterativeLinearSolvers", "Jacobi", "LU", "OrderingMethods", "QR", "SVD", "Sparse", "SparseCholesky", "SparseCore", "SparseLU", "SparseQR", "misc", "plugins") +eigen_modules <- c( + "Cholesky", + "Core", + "Dense", + "Eigenvalues", + "Geometry", + "Householder", + "IterativeLinearSolvers", + "Jacobi", + "LU", + "OrderingMethods", + "QR", + "SVD", + "Sparse", + "SparseCholesky", + "SparseCore", + "SparseLU", + "SparseQR", + "misc", + "plugins" +) eigen_files_to_vendor_src <- c() eigen_files_to_vendor_dst <- c() for (eigen_mod in eigen_modules) { - # Existing source files - eigen_module_subfolder_src <- paste0("deps/eigen/Eigen/src/", eigen_mod) - # eigen_module_filenames_src <- list.files(eigen_module_subfolder_src, recursive = TRUE) - # eigen_module_source_src <- file.path(eigen_module_subfolder_src, eigen_module_filenames_src) - eigen_module_source_src <- list.files(eigen_module_subfolder_src, recursive = TRUE, full.names = TRUE) - if (eigen_mod %in% c("misc", "plugins")) { - eigen_files_to_vendor_src <- c(eigen_files_to_vendor_src, eigen_module_source_src) - } else { - eigen_module_header_src <- file.path("deps/eigen/Eigen", eigen_mod) - eigen_files_to_vendor_src <- c(eigen_files_to_vendor_src, eigen_module_header_src, eigen_module_source_src) - } - - # Destination files - eigen_module_source_dst <- gsub("deps/eigen/Eigen", paste0(cran_dir, "/src/include/Eigen"), eigen_module_source_src) - if (eigen_mod %in% c("misc", "plugins")) { - eigen_files_to_vendor_dst <- c(eigen_files_to_vendor_dst, eigen_module_source_dst) - } else { - eigen_module_header_dst <- file.path(cran_dir, "src/include/Eigen", eigen_mod) - eigen_files_to_vendor_dst <- c(eigen_files_to_vendor_dst, eigen_module_header_dst, eigen_module_source_dst) - } + # Existing source files + eigen_module_subfolder_src <- paste0("deps/eigen/Eigen/src/", eigen_mod) + # eigen_module_filenames_src <- list.files(eigen_module_subfolder_src, recursive = TRUE) + # eigen_module_source_src <- file.path(eigen_module_subfolder_src, eigen_module_filenames_src) + eigen_module_source_src <- list.files( + eigen_module_subfolder_src, + recursive = TRUE, + full.names = TRUE + ) + if (eigen_mod %in% c("misc", "plugins")) { + eigen_files_to_vendor_src <- c( + eigen_files_to_vendor_src, + eigen_module_source_src + ) + } else { + eigen_module_header_src <- file.path("deps/eigen/Eigen", eigen_mod) + eigen_files_to_vendor_src <- c( + eigen_files_to_vendor_src, + eigen_module_header_src, + eigen_module_source_src + ) + } + + # Destination files + eigen_module_source_dst <- gsub( + "deps/eigen/Eigen", + paste0(cran_dir, "/src/include/Eigen"), + eigen_module_source_src + ) + if (eigen_mod %in% c("misc", "plugins")) { + eigen_files_to_vendor_dst <- c( + eigen_files_to_vendor_dst, + eigen_module_source_dst + ) + } else { + eigen_module_header_dst <- file.path( + cran_dir, + "src/include/Eigen", + eigen_mod + ) + eigen_files_to_vendor_dst <- c( + eigen_files_to_vendor_dst, + eigen_module_header_dst, + eigen_module_source_dst + ) + } } if (all(file.exists(eigen_files_to_vendor_src))) { - n_removed <- suppressWarnings(sum(file.remove(eigen_files_to_vendor_dst))) - if (n_removed > 0) { - cat(sprintf("Removed %d previously vendored files from src/include/Eigen\n", n_removed)) - } - - cat( - sprintf( - "Vendoring files from deps/eigen to src/include/Eigen\n" - ) + n_removed <- suppressWarnings(sum(file.remove(eigen_files_to_vendor_dst))) + if (n_removed > 0) { + cat(sprintf( + "Removed %d previously vendored files from src/include/Eigen\n", + n_removed + )) + } + + cat( + sprintf( + "Vendoring files from deps/eigen to src/include/Eigen\n" ) - - # Recreate the directory structure - dst_dirs <- unique(dirname(eigen_files_to_vendor_dst)) - for (dst_dir in dst_dirs) { - if (!dir.exists(dst_dir)) { - dir.create(dst_dir, recursive = TRUE) - } - } - - if (all(file.copy(eigen_files_to_vendor_src, eigen_files_to_vendor_dst))) { - cat("All Eigen files successfully copied to src/include/Eigen\n") - } else { - stop("Failed to vendor all Eigen files") + ) + + # Recreate the directory structure + dst_dirs <- unique(dirname(eigen_files_to_vendor_dst)) + for (dst_dir in dst_dirs) { + if (!dir.exists(dst_dir)) { + dir.create(dst_dir, recursive = TRUE) } + } + + if (all(file.copy(eigen_files_to_vendor_src, eigen_files_to_vendor_dst))) { + cat("All Eigen files successfully copied to src/include/Eigen\n") + } else { + stop("Failed to vendor all Eigen files") + } } # Clean up pragmas that suppress warnings in Eigen and JSON headers # File 1: Eigen "DisableStupidWarnings" header -cran_eigen_suppress_warnings <- file.path(cran_dir, "src/include/Eigen/src/Core/util/DisableStupidWarnings.h") +cran_eigen_suppress_warnings <- file.path( + cran_dir, + "src/include/Eigen/src/Core/util/DisableStupidWarnings.h" +) eigen_suppress_warnings_lines <- readLines(cran_eigen_suppress_warnings) for (i in 1:length(eigen_suppress_warnings_lines)) { - line <- eigen_suppress_warnings_lines[i] - eigen_suppress_warnings_lines[i] <- gsub("^.*#pragma clang diagnostic.*$", "", eigen_suppress_warnings_lines[i]) - eigen_suppress_warnings_lines[i] <- gsub("^.*#pragma diag_suppress.*$", "", eigen_suppress_warnings_lines[i]) - eigen_suppress_warnings_lines[i] <- gsub("^.*#pragma GCC diagnostic.*$", "", eigen_suppress_warnings_lines[i]) - eigen_suppress_warnings_lines[i] <- gsub("^.*#pragma region.*$", "", eigen_suppress_warnings_lines[i]) - eigen_suppress_warnings_lines[i] <- gsub("^.*#pragma endregion.*$", "", eigen_suppress_warnings_lines[i]) - eigen_suppress_warnings_lines[i] <- gsub("^.*#pragma warning.*$", "", eigen_suppress_warnings_lines[i]) + line <- eigen_suppress_warnings_lines[i] + eigen_suppress_warnings_lines[i] <- gsub( + "^.*#pragma clang diagnostic.*$", + "", + eigen_suppress_warnings_lines[i] + ) + eigen_suppress_warnings_lines[i] <- gsub( + "^.*#pragma diag_suppress.*$", + "", + eigen_suppress_warnings_lines[i] + ) + eigen_suppress_warnings_lines[i] <- gsub( + "^.*#pragma GCC diagnostic.*$", + "", + eigen_suppress_warnings_lines[i] + ) + eigen_suppress_warnings_lines[i] <- gsub( + "^.*#pragma region.*$", + "", + eigen_suppress_warnings_lines[i] + ) + eigen_suppress_warnings_lines[i] <- gsub( + "^.*#pragma endregion.*$", + "", + eigen_suppress_warnings_lines[i] + ) + eigen_suppress_warnings_lines[i] <- gsub( + "^.*#pragma warning.*$", + "", + eigen_suppress_warnings_lines[i] + ) } writeLines(eigen_suppress_warnings_lines, cran_eigen_suppress_warnings) From 32da5cda5d6f0a94fc7fc73da3df6e0e129b9566 Mon Sep 17 00:00:00 2001 From: Drew Herren Date: Fri, 21 Nov 2025 01:29:53 -0600 Subject: [PATCH 2/3] Updated CRAN comments and copyrights --- cran-comments.md | 3 +-- inst/COPYRIGHTS | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index 2ce42f9c..063c2208 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,8 +1,7 @@ ## R CMD check results -0 errors | 0 warnings | 3 notes +0 errors | 0 warnings | 2 notes -* This is a new release. * Checking installed package size ... NOTE installed size is 46.3Mb (linux-only) * Possibly misspelled words in DESCRIPTION: All of the words are proper nouns or technical terms (BCF, Carvalho, Chipman, McCulloch, XBART) diff --git a/inst/COPYRIGHTS b/inst/COPYRIGHTS index 71270347..c2188713 100644 --- a/inst/COPYRIGHTS +++ b/inst/COPYRIGHTS @@ -1,7 +1,7 @@ stochtree Copyright 2023-2025 stochtree contributors -Several stochtree C++ header and source files include or are inspired by code +Several stochtree C++ header / source files and build files include or are inspired by code in several open-source decision tree libraries: xgboost, LightGBM, and treelite. Copyright and license information for each of these three projects are detailed further below and in comments in each of the files. @@ -13,6 +13,11 @@ File: src/include/stochtree/log.h [LightGBM] File: src/include/stochtree/meta.h [LightGBM] File: src/include/stochtree/partition_tracker.h [LightGBM, xgboost] File: src/include/stochtree/tree.h [xgboost, treelite] +File: configure.ac [LightGBM] +File: configure.win [LightGBM] +File: cleanup [LightGBM] +File: Makevars.in [LightGBM] +File: Makevars.win.in [LightGBM] This project includes software from the xgboost project (Apache, 2.0). * Copyright 2015-2024, XGBoost Contributors From 74c6b7fc6db513f05d9cdf0face6b2d7c95595b5 Mon Sep 17 00:00:00 2001 From: Drew Herren Date: Fri, 21 Nov 2025 10:37:41 -0600 Subject: [PATCH 3/3] Increment version number --- Doxyfile | 2 +- configure | 19 ++++++++++--------- configure.ac | 2 +- pyproject.toml | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Doxyfile b/Doxyfile index 58837078..d8ea208e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = "StochTree" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.1.1 +PROJECT_NUMBER = 0.2.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/configure b/configure index 02737aa7..2480c9a9 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for stochtree 0.1.1. +# Generated by GNU Autoconf 2.72 for stochtree 0.2.0. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, @@ -600,8 +600,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stochtree' PACKAGE_TARNAME='stochtree' -PACKAGE_VERSION='0.1.1' -PACKAGE_STRING='stochtree 0.1.1' +PACKAGE_VERSION='0.2.0' +PACKAGE_STRING='stochtree 0.2.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1205,7 +1205,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures stochtree 0.1.1 to adapt to many kinds of systems. +'configure' configures stochtree 0.2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1267,7 +1267,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stochtree 0.1.1:";; + short | recursive ) echo "Configuration of stochtree 0.2.0:";; esac cat <<\_ACEOF @@ -1335,7 +1335,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stochtree configure 0.1.1 +stochtree configure 0.2.0 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1372,7 +1372,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stochtree $as_me 0.1.1, which was +It was created by stochtree $as_me 0.2.0, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -2385,7 +2385,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stochtree $as_me 0.1.1, which was +This file was extended by stochtree $as_me 0.2.0, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2440,7 +2440,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -stochtree config.status 0.1.1 +stochtree config.status 0.2.0 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" @@ -3000,3 +3000,4 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + diff --git a/configure.ac b/configure.ac index 6d59e3b0..c329eeb3 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ # https://github.com/microsoft/LightGBM/blob/master/R-package/configure.ac AC_PREREQ(2.69) -AC_INIT([stochtree], [0.1.1], [], [stochtree], []) +AC_INIT([stochtree], [0.2.0], [], [stochtree], []) # Note: consider making version number dynamic as in # https://github.com/microsoft/LightGBM/blob/195c26fc7b00eb0fec252dfe841e2e66d6833954/build-cran-package.sh diff --git a/pyproject.toml b/pyproject.toml index b1f18516..47545ff0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ build-backend = "setuptools.build_meta" [project] name = "stochtree" -version = "0.1.0" +version = "0.2.0" dynamic = ["readme", "optional-dependencies", "license"] description = "Stochastic Tree Ensembles for Machine Learning and Causal Inference" requires-python = ">=3.8.0"