/
merge.R
57 lines (51 loc) · 1.7 KB
/
merge.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#' Merge two configurations. Always use as `config::merge()`.
#'
#' Merge one configuration into another recursively.
#'
#' @section Warning - Do not attach the package using library(config):
#'
#' We strongly recommend you use `config::get()` rather than attaching the
#' package using `library(config)`.
#'
#' In fact, we strongly recommend you never use `library(config)`.
#'
#' The underlying reason is that the `get()` and `merge()` functions in
#' `{config}` will mask these functions with the same names in base R.
#'
#' @param base_config Configuration to merge values into
#'
#' @param merge_config Configuration to merge values from
#'
#' @return Configuration which includes the values from
#' `merge_config` merged into `base_config`.
#'
#' @seealso [get()]
#'
#' @export
merge <- function(base_config, merge_config) {
merge_lists(base_config, merge_config, recursive = TRUE)
}
# Recursively merge two lists (extracted from code used by rmarkdown
# package to merge _output.yml, _site.yml, front matter, etc.:
# https://github.com/rstudio/rmarkdown/blob/master/R/util.R#L174)
merge_lists <- function (base_list, overlay_list, recursive = TRUE) {
if (length(base_list) == 0)
overlay_list
else if (length(overlay_list) == 0)
base_list
else {
merged_list <- base_list
for (name in names(overlay_list)) {
base <- base_list[[name]]
overlay <- overlay_list[[name]]
if (is.list(base) && is.list(overlay) && recursive)
merged_list[[name]] <- merge_lists(base, overlay)
else {
merged_list[[name]] <- NULL
merged_list <- append(merged_list,
overlay_list[which(names(overlay_list) %in% name)])
}
}
merged_list
}
}