Skip to content

Commit f40d66f

Browse files
committed
use 'tools' for configure helpers
1 parent 62e2f7a commit f40d66f

File tree

8 files changed

+217
-55
lines changed

8 files changed

+217
-55
lines changed

cleanup

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env sh
2+
: ${R_HOME=`R RHOME`}
3+
"${R_HOME}/bin/R" --vanilla --slave -f tools/config/cleanup.R

cleanup.win

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env sh
2+
"${R_HOME}/bin${R_ARCH_BIN}/R.exe" --vanilla --slave -f tools/config/cleanup.R

configure

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
#!/usr/bin/env sh
12
: ${R_HOME=`R RHOME`}
2-
"${R_HOME}/bin/R" --vanilla --slave -f R/config/configure.R
3+
"${R_HOME}/bin/R" --vanilla --slave -f tools/config/configure.R

configure.win

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
: ${R_HOME=`R RHOME`}
2-
"${R_HOME}/bin/R.exe" --vanilla --slave -f R/config/configure.R
1+
#!/usr/bin/env sh
2+
"${R_HOME}/bin${R_ARCH_BIN}/R.exe" --vanilla --slave -f tools/config/configure.R

tools/config/cleanup.R

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# utils.R ----
2+
3+
#' Configure a File
4+
#'
5+
#' Configure a file, replacing any instances of `@`-delimited variables, e.g.
6+
#' `@VAR@`, with the value of the variable called `VAR` in the associated
7+
#' `config` environment.
8+
#'
9+
#' @param source The file to be configured.
10+
#' @param target The file to be generated.
11+
#' @param config The configuration environment.
12+
#' @param verbose Boolean; report files as they are configured?
13+
#'
14+
#' @export
15+
configure_file <- function(
16+
source,
17+
target = sub("[.]in$", "", source),
18+
config = NULL,
19+
verbose = getOption("configure.verbose", TRUE))
20+
{
21+
contents <- readLines(source, warn = FALSE)
22+
enumerate(config, function(key, val) {
23+
needle <- paste("@", key, "@", sep = "")
24+
replacement <- val
25+
contents <<- gsub(needle, replacement, contents)
26+
})
27+
28+
ensure_directory(dirname(target))
29+
writeLines(contents, con = target)
30+
31+
if (isTRUE(verbose)) {
32+
fmt <- "** configured file: '%s' => '%s'"
33+
message(sprintf(fmt, source, target))
34+
}
35+
}
36+
37+
#' Read R Configuration for a Package
38+
#'
39+
#' Read the \R configuration, as through `R CMD config --all`.
40+
#'
41+
#' @param package The path to an \R package's sources.
42+
#' @param values The \R configuration values to read (as a character vector).
43+
#' If `NULL` (the default), all values are read (as through `R CMD config --all`).
44+
#' @param verbose Boolean; notify the user as \R configuration is read?
45+
#'
46+
#' @export
47+
read_config <- function(
48+
package = ".",
49+
values = NULL,
50+
verbose = getOption("configure.verbose", TRUE))
51+
{
52+
# move to requested directory
53+
owd <- setwd(package)
54+
on.exit(setwd(owd), add = TRUE)
55+
R <- file.path(R.home("bin"), "R")
56+
57+
if (is.null(values)) {
58+
if (verbose)
59+
message("** executing 'R CMD config --all'")
60+
output <- system2(R, c("CMD", "config", "--all"), stdout = TRUE)
61+
equalsIndex <- regexpr("=", output, fixed = TRUE)
62+
keys <- trim_whitespace(substring(output, 1, equalsIndex - 1))
63+
config <- as.list(trim_whitespace(substring(output, equalsIndex + 1)))
64+
names(config) <- keys
65+
66+
} else {
67+
if (verbose)
68+
message("** executing 'R CMD config'")
69+
config <- lapply(values, function(value) {
70+
system2(R, c("CMD", "config", value), stdout = TRUE)
71+
})
72+
names(config) <- values
73+
}
74+
75+
list2env(config, parent = globalenv())
76+
}
77+
78+
#' Concatenate the Contents of a Set of Files
79+
#'
80+
#' Given a set of files, concatenate their contents into
81+
#' a single file.
82+
#'
83+
#' @param sources An \R list of files
84+
#' @param target The file to use for generation.
85+
#' @param headers Headers to be used for each file copied.
86+
#'
87+
#' @export
88+
concatenate_files <- function(
89+
sources,
90+
target,
91+
headers = sprintf("# %s ----", basename(sources)))
92+
{
93+
pieces <- vapply(seq_along(sources), function(i) {
94+
source <- sources[[i]]
95+
header <- headers[[i]]
96+
contents <- trim_whitespace(read_file(source))
97+
paste(header, contents, "", sep = "\n\n")
98+
}, character(1))
99+
100+
ensure_directory(dirname(target))
101+
writeLines(pieces, con = target)
102+
}
103+
104+
ensure_directory <- function(dir) {
105+
info <- file.info(dir)
106+
107+
# no file exists at this location; try to make it
108+
if (is.na(info$isdir)) {
109+
dir.create(info$isdir, recursive = TRUE, showWarnings = FALSE)
110+
if (!file.exists(dir))
111+
stop("failed to create directory '", dir, "'")
112+
return(TRUE)
113+
}
114+
115+
# a directory already exists
116+
if (isTRUE(info$isdir))
117+
return(TRUE)
118+
119+
# a file exists, but it's not a directory
120+
stop("file already exists at path '", dir, "'")
121+
}
122+
123+
enumerate <- function(x, f, ...) {
124+
nms <- if (is.environment(x)) ls(envir = x) else names(x)
125+
lapply(nms, function(nm) {
126+
f(nm, x[[nm]], ...)
127+
})
128+
}
129+
130+
read_file <- function(path) {
131+
paste(readLines(path, warn = FALSE), collapse = "\n")
132+
}
133+
134+
remove_file <- function(
135+
path,
136+
verbose = getOption("configure.verbose", TRUE))
137+
{
138+
info <- file.info(path)
139+
if (!is.na(info$isdir)) {
140+
unlink(path, recursive = isTRUE(info$isdir))
141+
if (verbose) {
142+
fmt <- "** removed file '%s'"
143+
message(sprintf(fmt, path))
144+
}
145+
}
146+
147+
TRUE
148+
}
149+
150+
trim_whitespace <- function(x) {
151+
gsub("^[[:space:]]*|[[:space:]]*$", "", x)
152+
}
153+
154+
155+
# run-cleanup.R ----
156+
157+
# figure out the current package's name
158+
DESCRIPTION <- read.dcf("DESCRIPTION", all = TRUE)
159+
fmt <- "* configuring package '%s' ..."
160+
message(sprintf(fmt, DESCRIPTION$Package))
161+
162+
# overlay user configuration
163+
envir <- new.env(parent = globalenv())
164+
files <- list.files("tools/config/cleanup", pattern = "[.][rR]$", full.names = TRUE)
165+
for (file in files) {
166+
fmt <- "** sourcing '%s'"
167+
message(sprintf(fmt, file))
168+
source(file, local = envir)
169+
}
170+
171+
# apply cleanup script (if any)
172+
if (exists("cleanup", envir = envir, inherits = FALSE)) {
173+
cleanup <- get("cleanup", envir = envir, inherits = FALSE)
174+
message("** executing user-defined cleanup script")
175+
cleanup()
176+
}
177+
178+
fmt <- "* successfully cleaned package '%s'"
179+
message(sprintf(fmt, DESCRIPTION$Package))
180+
181+

tools/config/cleanup/clean.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
clean <- function() {
2+
remove_file("src/Makevars")
3+
}
Lines changed: 18 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
configure_file <- function(
1616
source,
1717
target = sub("[.]in$", "", source),
18-
config = read_config(),
18+
config = NULL,
1919
verbose = getOption("configure.verbose", TRUE))
2020
{
2121
contents <- readLines(source, warn = FALSE)
@@ -131,51 +131,24 @@ read_file <- function(path) {
131131
paste(readLines(path, warn = FALSE), collapse = "\n")
132132
}
133133

134-
trim_whitespace <- function(x) {
135-
gsub("^[[:space:]]*|[[:space:]]*$", "", x)
136-
}
137-
138-
139-
# use-configure.R ----
140-
141-
#' Add Configure Infrastructure to an R Package
142-
#'
143-
#' Add the infrastructure needed to configure an R package.
144-
#'
145-
#' @param package The path to the top-level directory of an \R package.
146-
#' @export
147-
use_configure <- function(package = ".") {
148-
149-
# preserve working directory
150-
owd <- getwd()
151-
on.exit(setwd(owd), add = TRUE)
152-
153-
# find resources
154-
package <- normalizePath(package, winslash = "/")
155-
resources <- system.file("resources", package = "configure")
156-
157-
# copy into temporary directory
158-
dir <- tempfile("configure-")
159-
on.exit(unlink(dir, recursive = TRUE), add = TRUE)
160-
161-
dir.create(dir)
162-
file.copy(resources, dir, recursive = TRUE)
163-
164-
# rename resources directory
165-
setwd(dir)
166-
file.rename(basename(resources), basename(package))
134+
remove_file <- function(
135+
path,
136+
verbose = getOption("configure.verbose", TRUE))
137+
{
138+
info <- file.info(path)
139+
if (!is.na(info$isdir)) {
140+
unlink(path, recursive = isTRUE(info$isdir))
141+
if (verbose) {
142+
fmt <- "** removed file '%s'"
143+
message(sprintf(fmt, path))
144+
}
145+
}
167146

168-
# now, copy these files back into the target directory
169-
file.copy(basename(package), dirname(package), recursive = TRUE)
147+
TRUE
148+
}
170149

171-
# ensure DESCRIPTION contains 'Biarch: TRUE' for Windows
172-
setwd(package)
173-
DESCRIPTION <- read_file("DESCRIPTION")
174-
if (!grepl("(?:^|\n)Biarch:", DESCRIPTION)) {
175-
DESCRIPTION <- paste(DESCRIPTION, "Biarch: TRUE", sep = "\n")
176-
DESCRIPTION <- gsub("\n{2,}", "\n", DESCRIPTION)
177-
cat(DESCRIPTION, file = "DESCRIPTION", sep = "\n")
178-
}
150+
trim_whitespace <- function(x) {
151+
gsub("^[[:space:]]*|[[:space:]]*$", "", x)
179152
}
180153

181154

@@ -188,7 +161,7 @@ message(sprintf(fmt, DESCRIPTION$Package))
188161

189162
# overlay user configuration
190163
envir <- new.env(parent = globalenv())
191-
files <- list.files("R/config/scripts", pattern = "[.][rR]$", full.names = TRUE)
164+
files <- list.files("tools/config/configure", pattern = "[.][rR]$", full.names = TRUE)
192165
for (file in files) {
193166
fmt <- "** sourcing '%s'"
194167
message(sprintf(fmt, file))
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
configure <- function() {
22

3-
if (Sys.info()[["sysname"]] == "Windows") {
4-
configure_file("src/Makevars.in", "src/Makevars.win")
5-
} else {
6-
configure_file("src/Makevars.in", "src/Makevars")
7-
}
8-
93
if (getRversion() < "3.4.0") {
104
config <- list(
115
CC = "$(CC)",
@@ -23,6 +17,11 @@ configure <- function() {
2317
}
2418

2519
config$STDVER <- "c++11"
20+
if (Sys.info()[["sysname"]] == "Windows") {
21+
configure_file("src/Makevars.in", "src/Makevars.win", config = config)
22+
} else {
23+
configure_file("src/Makevars.in", "src/Makevars", config = config)
24+
}
2625

2726
config
28-
}
27+
}

0 commit comments

Comments
 (0)