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"