Including extra functions in carrier::crate in R, manual environment creation in R

  carrier, docker, r, rlang

I’m trying to create standalone function with carrier::crate in R that could be exported in environment (i.e. a docker container) without the libraries in the original session but with no luck. The example is modified from this blog post. I’m using styler package as an example. I ran in problems with inherited dependencies and probably this hack isn’t worth the effort.

However I would like to understand what is happening here. Why aren’t the declared functions in import_env2 found in the crated function?


First R-base environment (docker run -it -v <repopath>:<repopath> r-base):

install.packages(c("styler", "pkgload", "carrier"))

# incude imported functions
import_env <- rlang::ns_imports_env("styler")
imported_functions_names <- ls(import_env)

imported_functions_to_declare <- lapply(
  imported_functions_names,
  function(x) rlang::expr(import_env[[!!x]])
)
names(imported_functions_to_declare) <- imported_functions_names

# declare package functions and data
pgk_path <- "<path_to_styler_source>"
package_name <- pkgload::pkg_name(pgk_path)
pkgload::load_all(pgk_path)
package_namespace_ls <- ls(getNamespace(package_name))

package_functions_to_set_env <- lapply(package_namespace_ls, function (x) {
  if(is.function(get(x))) rlang::expr(rlang::set_env(!!rlang::sym(x)))
})
names(package_functions_to_set_env) <- package_namespace_ls
package_functions_to_set_env <- package_functions_to_set_env[!sapply(package_functions_to_set_env,is.null)]

package_data_to_set_env <- lapply(package_namespace_ls, function (x) {
  if(!is.function(get(x))) rlang::expr(!!rlang::sym(x))
})
names(package_data_to_set_env) <- package_namespace_ls
package_data_to_set_env <- package_data_to_set_env[!sapply(package_data_to_set_env,is.null)]


# manually pick some functions that are not included in above list for some reason
# FIXME: why is this failing?
import_env2 <- rlang::env()
rlang::env_bind(import_env2, enquos = rlang::enquos)
rlang::env_bind(import_env2, quo_invert = purrr:::quo_invert)
extra_functions_names <- ls(import_env2)

extra_functions_to_declare <- lapply(
  extra_functions_names,
  function(x) rlang::expr(import_env2[[!!x]])
)
names(extra_functions_to_declare) <- extra_functions_names

# crate the function
fun <- carrier::crate(
  ~style_text(.x),
  !!!package_functions_to_set_env,
  !!!package_data_to_set_env,
  !!!imported_functions_to_declare,
  !!!extra_functions_to_declare
  )

# save crated function
save(fun, file = "<fun_file>")

Clean R-base environment (docker run -it -v <repopath>:<repopath> r-base):

> load("<fun_file>")
Warning: namespace ‘rlang’ is not available and has been replaced
by .GlobalEnv when processing object ‘fun’
Warning: namespace ‘tibble’ is not available and has been replaced
by .GlobalEnv when processing object ‘fun’
Warning: namespace ‘styler’ is not available and has been replaced
by .GlobalEnv when processing object ‘fun’
Warning: namespace ‘purrr’ is not available and has been replaced
by .GlobalEnv when processing object ‘fun’
Warning: namespace ‘pillar’ is not available and has been replaced
by .GlobalEnv when processing object ‘fun’
Warning: namespace ‘magrittr’ is not available and has been replaced
by .GlobalEnv when processing object ‘fun’
> fun("test")
Error in enquos(...) : could not find function "enquos"

Source: Docker Questions

LEAVE A COMMENT